Quantcast
Channel: Active Directory Federation Services – Hybrid Identity
Viewing all 26 articles
Browse latest View live

Deploying a federation server with a SQL database

$
0
0

This post is as much for me as anyone else (because I’ve done and forgotten how to do this three times thus I am writing it down). If you want to stand up a new Active Directory Federation Services (AD FS) 2.0 federation server as the first server in a farm using a SQL backend this is what you need to do.

Note. When setting up labs I generally configure “farms” of one server. For me this is more representative of what I’ll encounter in the real world. Even if you’re not planning on scaling out at the moment it is probably at least worth testing a configuration that will likely be deployed in production at least once before you try for real in pre-production.

This post dives directly into the configuration. I’m therefore assuming the following:

  • You’ve built either a full installation of Windows Server 2008 x64 Service Pack 2 or Windows Server 2008 R2 Service Pack 1.
  • You’ve joined the machine to your AD DS domain.
  • You’ve installed AD FS 2.0.
  • You’ve enrolled a Web Server certificate and created a HTTPS binding for the Default Web Site.
  • You’ve created a service account for AD FS 2.0 and created the necessary HOST Service Principal Name (SPN).

Information on how to perform the latter three bullets can be found by following the links on this TechNet checklist:

AD FS must be installed first. The configuration is then achieved using FSCONFIG.EXE.

SQL Server

The FSCONFIG.EXE installation/configuration tool will create the SQL database if the context it is running under is able to do so, i.e. you have the necessary permissions in the SQL server you tell the tool to use. However if you don’t have the necessary permissions to do this then you can generate the necessary TSQL and provide .SQL scripts to the SQL Server administrators.

To generate the SQL scripts you run FSCONFIG with the following command line parameters:

fsconfig GenerateSQLScripts /ServiceAccount CORP\svcadfs /ScriptDestinationFolder d:\deploy\adfs\adfsSqlScripts 

Configuring the AD FS server with an account that has permission to create the SQL database

A clean installation, without the need for SQL DBA scripts, is achieved using FSCONFIG with the CREATESQLFARM command as follows.

PS C:\Program Files\Active Directory Federation Services 2.0> .\FsConfig.exe createsqlfarm /serviceaccount
CORP\svcadfs /sqlconnectionstring "database=adfscfg;server=sql\idmdbs;integrated security=sspi" /autocertrolloverenabled
Enter a password for CORP\svcadfs:******** 
Creating a new federation server farm... 
Stopping the AD FS 2.0 Windows Service... 
Passed 
Configuring the AD FS configuration database... 
Passed 
Creating an Active Directory container for sharing signing and decryption certificates... 
Passed 
Configuring certificates, service settings, and endpoints... 
Passed 
Deploying the browser sign-in Web site to the /adfs/ls virtual directory under the Default Web Site in IIS... 
Passed 
Starting the AD FS 2.0 Windows Service... 
Passed 
Creating default claim set... 
Passed 
Creating default claim acceptance rules on the Active Directory claims provider trust 
Passed 
Configuration is complete. 

Here’s the screenshot:

Configuring the AD FS server with an account that does not have permission to create the SQL database

If the database exists, i.e. a SQL DBA pre-created it and you want to start over, as opposed to join, you use the CLEANCONFIG switch in conjunction with the CREATESQLFARM, as follows.

C:\Program Files\Active Directory Federation Services 2.0>fsconfig createsqlfarm 
/serviceaccount corp\svcadfs /sqlconnectionstring "database=adfsconfiguration;server=adfs\idmsys;integrated security=sspi" 
/autocertrolloverenabled /cleanconfig 
Enter a password for corp\svcadfs:******** 
Creating a new federation server farm... 
Stopping the AD FS 2.0 Windows Service... 
Passed 
Configuring the AD FS configuration database... 
Passed 
Creating an Active Directory container for sharing signing and decryption certificates... 
Passed 
Configuring certificates, service settings, and endpoints... 
Passed 
Deploying the browser sign-in Web site to the /adfs/ls virtual directory under the Default Web Site 
in IIS... 
Passed 
Starting the AD FS 2.0 Windows Service... 
Passed 
Creating default claim set... 
Passed 
Creating default claim acceptance rules on the Active Directory claims provider trust 
Passed 
Configuration is complete. 

Here’s the screenshot:

Joining an additional node to the farm

Once the farm is created you join additional nodes to the farm using the following syntax where the thumbprint is that of the service certificate configured within the farm.

C:\Program Files\Active Directory Federation Services 2.0>fsconfig joinsqlfarm /serviceaccount corp\svcadfs /sqlconnectionstring "database=adfsconfiguration;server=adfs\idmsys;integrated security=sspi" /certthumbprint "91 f4 55 10 e9 04 18 ea 16 af 0b eb a5 13 ce f1 36 64 6c 69" 
Enter a password for corp\svcadfs:******** 

A discussion on the certificate requirement and options is probably a good subject for a future blog post.

Wrap-up

I used automatic certificate rollover above because I’m lazy. I installed the service, setup the farm and then changed the signing and decrypting certificates using the UI. This is a little backward for anywhere other than a lab. In a real environment the certificates will be installed and you’ll utilise the following command instead:

C:\Program Files\Active Directory Federation Services 2.0>fsconfig createsqlfarm /serviceaccount corp\svcadfs /sqlconnectionstring "database=adfsconfiguration;server=adfs\idmsys;integrated security=sspi" /signingcertthumbprint "91 f4 55 10 e9 04 18 ea 16 af 0b eb a5 13 ce f1 36 64 6c 69" /decryptcertthumbprint "91 f4 55 10 e9 04 18 ea 16 af 0b eb a5 13 ce f1 36 64 6c 69" 
Enter a password for corp\svcadfs:********

If I were to use any kind of real excuse for this I would say it was so that I could post both variants of the command: that that generates the self-signed certificate and that that specifically references an existing, proper certificate.



Active Directory Federation Services (AD FS) 2.0 and multiple AD DS forests

$
0
0

Something that wasn’t immediately clear (from the UX) or easily obtainable (via Internet search) was information on what configuration, if any, is required in Active Directory Federation Services 2.0 (AD FS 2.0) in an environment where there is multiple Active Directory Domain Services (AD DS) forests and/or domains. And it wasn’t just me either, as I’ve been asked by both colleagues and customers. J

Put simply there’s no need for any configuration in the AD FS 2.0 Management user interface (UI). When you install AD FS an implicit, enabled Claims Provider (CP) Trust for the Active Directory domain in which the server(s) hosting the AD FS instance reside is created. Subsequent access to the federation server (FS) is governed by the ability to authenticate to the FS. That is, if you’ve been authenticated by any of the permissible systems on the other end of the CP trust you are subject to the applicable policy and rules of the relying party (RP) trust.

The FS is actually a .NET web service. Authentication to the FS (or STS) is therefore a feature of Internet Information Services (IIS) which means that if the trust direction is such that users can authenticate in the domain that hosts AD FS then users can authenticate to the FS.

Note. AD FS supports Integrated Windows authentication (IWA); Forms-based authentication (FBA); Transport layer security client authentication (certificates); and basic authentication. I’m specifically addressing the default behaviour for internal Internet Explorer clients. For more information on how to configure the different authentication types refer to the TechNet wiki article AD FS 2.0: How to Change the Local Authentication Type.

The only caveat to the statement that there’s no need for configuration in AD FS 2.0 is that you might, depending on the configuration of directory permissions and LDAP queries performed by AD FS for the purpose of claim values, need to permit access to certain LDAP attributes, in the adjacent domains, to the AD FS service account.

To put this into perspective, let’s look at a couple of examples.

Example 1: two single-domain forests

In this example there are two AD forests, each housing one domain. The OS level is pretty irrelevant to AD FS but I include it for completeness and to permit a forest trust (not strictly true, but I like to use Kerberos wherever possible).

AD FS is installed in infra.adatum.com and the majority of the user population resides in users.adatum.com. Service accounts are considered infrastructure therefore they reside in infra.adatum.com. Because the service account running the AD FS farm is a principal in infra.adatum.com a bidirectional trust is needed, as the service account performs attribute value lookups, using LDAP, in the users.adatum.com domain. If the service account belonged to the users.adatum.com domain a unidirectional trust between the domains (incoming in users.adatum.com, i.e. users.adatum.com users can authenticate in infra.adatum.com would suffice.)

Example 2: three AD DS forests

In this example there are three single-domain forests. AD FS is installed in the new corp.adatum.com forest and will originally be used for the purpose of internal claims-based authentication (AuthN), i.e. several ASP.NET applications have been migrated to use Windows Identity Framework (WIF) and require a CP to service authentication.

Bidirectional trusts are now mandatory as is the location of the service account. In this example the service account must exist in the corp.adatum.com domain which trusts, and is trusted by, each of the other domains.

Trust types

There’s no real dependency on trust type. Forest trusts or external trusts are valid. You just need to ensure that they’re bidirectional in most instances because of the need to do LDAP queries to build claim values.

Wrap-up

When considering internal authentication to the CP (STS) in almost all circumstances the default behaviour of Integrated Windows Authentication will be used.

In a forest with multiple domains there is nothing to configure or do because of the implicit bidirectional transitive trusts in place. Users will be able to authenticate to the AD FS web service and the AD FS service account will be able to read LDAP attribute values (unless you’ve hardened your AD DS ACLs).

In an environment that consists of more than one forest there is a requirement for AD DS trusts if you don’t want to implement multiple AD FS instances and federate them. In this case external or forests trusts will work. In most cases you will require bidirectional trusts. There are only a small number of cases whereby you can enable everything to work with a unidirectional trust.

There is no dependency on the AD DS domain or forest functional levels or schema. If you want proof of this look to the MSIT case study – Microsoft have 15 domains in 4 forests running, at some point in time, a rather mixed mode environment in terms of AD versions and have a very busy AD FS implementation –one instance, servicing everything.


Update Rollup 1 for Active Directory Federation Services (AD FS) 2.0

$
0
0

Yesterday Microsoft released Update Rollup 1 for Active Directory Federation Services (AD FS) 2.0.

The update includes hotfixes and updates that fix seven (7) product issues and add four (4) new capabilities to the product. Summarised, the changes are:

  • Issue 1 (kb2254265): The “500″ error code is returned when you send an HTTP SOAP request to the “/adfs/services/trust/mex” endpoint on a computer that is running Windows Server 2008 R2 or Windows Server 2008
  • Issue 2 (kb2272757): An identity-provider-initiated sign-on process is slow in Windows Server 2008 R2 and in Windows Server 2008
  • Issue 3: The “400″ error code is returned when sending an authentication request to AD FS 2.0 federation server proxy through Windows integrated authentication endpoint (Nego 2)
  • Issue 4: Decrease in performance occurs on AD FS 2.0 federation server when a user who is authenticating has a large number of group memberships.
  • Issue 5: Failure to join an AD FS 2.0 federation server to an existing SQL-based federation server farm when the AD FS 2.0 administrator that tries the join operation does not have administrator rights to the SQL Server database.
  • Issue 6: AD FS 2.0 Federation Service cannot create or verify SAML tokens when the private keys of an AD FS 2.0 token-signing certificate and/or token decryption certificate are stored by using third-party cryptographic service providers (CSP), for example hardware security mode (HSM).
  • New capability 1: Multiple Issuer Support
  • New capability 2: Client Access Policy Support
  • New capability 3: Congestion Control Algorithm
  • New capability 4: Additional AD FS 2.0 performance counters

Those of you working on Office 365 projects might find this new capability of particular interest:

Multiple Issuer Support. Previously, Microsoft Office 365 customers who require single sign-on (SSO) by using AD FS 2.0 and use multiple top level domains for users’ user principal name (UPN) suffixes within their organization (for example, @contoso.us or @contoso.de) are required to deploy a separate instance of AD FS 2.0 Federation Service for each suffix. After you install this Update Rollup on all the AD FS 2.0 federation servers in the farm and follow the instructions of using this feature with Office 365, new claim rules will be set to dynamically generate token issuer IDs based on the UPN suffixes of the Office 365 users. As a result, you do not have to set up multiple instances of AD FS 2.0 federation server to support SSO for multiple top level domains in Office 365.

For more information about the instructions, visit the following Microsoft website: General information about how to set up a trust by adding or converting a domain for SSO


Update Rollup 2 for Active Directory Federation Services (AD FS) 2.0

$
0
0

Yesterday Microsoft released Update Rollup 2 for Active Directory Federation Services (AD FS) 2.0.

This update rollup includes hotfixes and updates that fix four (4) product issues and add one (1) new capability to the product.  Summarised, the changes are as follows.

New capability

  • AD FS 2.0 does not fully support the RelayState parameter for Security Assertion Markup Language (SAML) protocol.  Update Rollup 2 for AD FS 2.0 adds a new capability that enables AD FS 2.0 to consume relay state in order to redirect the user to the RP application.

For more information on this new capability please see Supporting Identity Provider Initiated RelayState.

Product issues resolved

  • Issue 1: There is a reliability issue in AD FS 2.0 in which AD FS 2.0 Federation Service stops responding to requests in certain cases, especially when there is a large load on AD FS 2.0 federation server or federation server proxy.  This issue can occur in both federation passive and federation active scenarios.
  • Issue 2: The whr parameter that is specified by an application for a home realm discovery scenario overwrites the previously set home realm discovery cookie.  This causes a user to be redirected to a different identity provider that the user cannot use to sign in when the user uses a different application.
  • Issue 3: The AD FS 2.0 service stops unexpectedly when a valid certificate is set to the archived state.
  • Issue 4: When you add an AD FS 2.0 federation server to a Windows Internal Database (WID) farm, you receive an error message.  This issue occurs when the federation server is in a time zone that is later than the primary federation server in the WID farm.

AD FS 2.0 Issuance Authorization Rules

$
0
0

I had to create a couple of issuance authorization rules in my last engagement and it took me a little longer than it should have to get the syntax correct so I thought I’d post a couple of examples that might be of interest to others.

Firstly, lets clarify what I’m talking about.  Taken from When to Use an Authorization Claim Rule in the AD FS 2.0 Design Guide:

You can use this rule in Active Directory Federation Services (AD FS) 2.0 when you need to take an incoming claim type and then apply an action that will determine whether a user will be permitted or denied access based on the value that you specify in the rule. When you use this rule, you pass through or transform claims that match the following rule logic, based on either of the options you configure in the rule:

To wrap some further context around this post you define issuance authorization rules on relying party trusts.  These rules are applied early on in the claims pipeline process.  You use issuance authorization rules to determine whether or not a user has access to an relying party application. 

A common issuance authorization rule is the permit access to all users rule template.  If you look at the underlying claim rule language for this template you will see the following:

=> issue(Type = “http://schemas.microsoft.com/authorization/claims/permit”, Value = “true”);

Nice and easy.  Issue a claim of the type http://schemas.microsoft.com/authorization/claims/permit with a value of true. 

It’s worth pointing out here that the value is irrelevant.  The authorisation engine only looks for the type of claim, allowing access if there is a claim with a type of http://schemas.microsoft.com/authorization/claims/permit, and not allowing access if there’s no permit claim type or if there is a claim with a type of  http://schemas.microsoft.com/authorization/claims/deny present.  More information on this here.

The purpose of this post is to share two simple examples.  I just designed an AD FS solution and made use of authorization rules to achieve the requirement of all users in domain-a have access to RP application XYZ.  In this environment there were three domains in the forest.  We only wanted users in one of the domains to access the application.  I achieved this by creating a rule with the Send Claims Using a Custom Rule template and the following rule:

c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Value =~ "^(?i)CORP\\.+$"]
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/permit”, Value = “true”);

To explain the rule lets assume we have the following domains in the forest: corp.contoso.com, partner.contoso.com, and emea.corp.contoso.com.  The above claim rule only permits access to a relying party if the Windows account name (http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname) claim type has a value of CORP\something, e.g. CORP\paulw or CORP\chucn.

Next we had a similar requirement that we achieved with a rule around the value of the UPN claim type.  We wanted partners to be able to access an RP.  Non-employee accounts in the directory had a different UPN suffix to employees and contractors (non-employee accounts are created in partner.contoso.com if the partner organisation doesn’t have federation infrastructure).  In this scenario we decided to permit access to an RP application for all users with a UPN of something@partner.contoso.com.  Here’s an example:

c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn", Value =~ "^(?i).+@partner\.contoso\.com$"]
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/permit”, Value = “true”);

Hopefully this will help someone.  It took me longer than it should have to get the regex right.  Smile

Just in case you need a little more guidance on how to create these rules…

If you’re new to AD FS and have just read the above and are thinking awesome, I really want to use that UPN rule but…I have no idea how to create it here goes…

  1. Open AD FS 2.0 management console, click Relying Party Trusts, click the RP trust that you want to configure and click Edit Claim Rules… in the actions bar.
  2. The Edit Claim Rules for <RP name> dialog opens.  Click the Issuance Authorization Rules tab (the middle tab).  If you’re accessing the RP presently you likely have a single rule called Permit Access to All Users with an issued claims of Permit in the list.  Remove this rule and click Add Rule…
  3. Choose the Send Claims Using a Custom Rule template and click Next.
  4. Supply a name and then paste your syntax into the custom rule input.  Click Finish.

If you consider the following rule:

c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn", Value =~ "^(?i).+@partner\.contoso\.com$"]
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/permit&#8221;, Value = “true”);

The part that you need to configure is the regex –the contents within the quotes after =~ e.g. ^(?i).+@partner\.contoso\.com$.

Regarding the regex.

  • (?i) makes the pattern case insensitive.
  • ^ means starts with.
  • .+ means anything one or more times.
  • @partner\.contoso\.com is the URL with an escape sequence for the dot (or period).
  • $ means ends with.

Uninstalling AD FS 2.0 (and deleting the databases)

$
0
0

I’ve been working on an installation guide for AD FS 2.0 and have needed to uninstall and reinstall several times.  When you uninstall AD FS the database isn’t deleted.  The IIS applications aren’t removed and the token signing objects in AD DS aren’t removed.  Microsoft Support knowledgebase article kb982813 How to restore IIS and clean up Active Directory when you uninstall Active Directory Federation Services 2.0 describes how to remove the AD DS objects and the IIS applications and virtual directories but does not explain how to remove the AD FS database.  This isn’t a major problem as the FsConfig.exe configuration tool has a /cleanconfig switch that will drop and create new databases however when you’re developing guidance for others you can’t really use the CLEAN switch and therefore need to be able to effectively remove the database.  The following instructions explain how to do this.  AD FS 2.0: Migrate Your AD FS Configuration Database to SQL Server was the guiding factor in putting this post together.

Here’s what I had to do and did.

Note.

If you are following these instructions and still have a working AD FS skim down to the clean up AD DS section and perform those steps first.

Uninstall AD FS 2.0

  1. Open APPWIZ.CPL.
  2. Click View Installed Updates and type ACTIVE into the Search Programs and Features search bar.
  3. Select Active Directory Federation Services 2.0 and click Uninstall.

Remove databases from WID

  1. Downloaded and installed SQL Server 2008 R2 Express Management Tools.
  2. Using SQL Server Management Studio (SSMS) connected to:
    \\.\pipe\MSSQL$MICROSOFT##SSEE\sql\query
  3. Executed the following T-SQL script:
    use master;
    go
    sp_detach_db 'adfsconfiguration';
    go
    sp_detach_db 'adfsartifactstore';
    go
    
  4. When complete I deleted the data files:
    del C:\Windows\SYSMSI\SSEE\MSSQL.2005\MSSQL\Data\adfs*

Uninstall WID

Lastly, you can remove WID using Server Manager, e.g.

Import-Module ServerManager
Get-WindowsFeature | ? {
	$_.Installed -and
	$_.Name -eq 'Windows-Internal-DB'
 } | Remove-WindowsFeature

Clean up and uninstall IIS

Next you need to clean up IIS as per kb982813:

  1. Open IIS manager.  Expand <server> | Sites | Default Web Site | adfs
  2. Right-click on ls and click Remove
  3. Right-click on adfs and click RemoveBe sure to remove LS and then ADFS and don’t just remove ADFS otherwise you’ll be in the applicationHost.config deleting XML elements.
  4. Click Application Pools (further up the tree) and right-click on ADFSAppPool and click Remove.
  5. Lastly delete the folders and files.
    Remove-Item C:\inetpub\adfs -Recurse

Clean up AD DS

Ideally this step is first –then you can do this:

Add-PSSnapin microsoft.adfs.powershell
(Get-ADFSProperties).CertificateSharingContainer

Which gives you the DN, e.g.

image

But more often than not we read the instructions last.  So we need to delete the container with a CN of the GUID of your AD FS farm from CN=Microsoft, CN=Program Data, DC=your-domain, DC=tld.

image

In the case of the above picture I’ve stood up and torn down five AD FS farms.  All of these certificate sharing containers need to go.  But you need to be careful here.  Please be sure there aren’t other active AD FS farms in the domain before you delete them!

And regarding deleting, I’m a big user of LDP but also like PowerShell and often don’t have access to ADWS (Active Directory Web Services) so here’s a little snippet for delete using S.DS (System.DirectoryServices).

$delme = New-Object System.DirectoryServices.DirectoryEntry(
    "LDAP://CN=42bc22f5-e636-412f-9175-ba75912d4b4a,CN=ADFS,CN=Microsoft,CN=Program Data,DC=rnd,DC=litware-inc,DC=com")
$delme.DeleteTree()

Wrap-up

At this point all should be removed and all well.  If you deleted the ADFS application before you deleted the LS application read on.  I hope this post has been helpful!

Application pool ‘ADFSAppPool’ cannot be deleted because it contains 1 applications

If you got the order wrong and you get the error: “Application pool ‘ADFSAppPool’ cannot be deleted because it contains 1 applications.” (dialog below) you need to perform the following steps.

image

  1. Open an elevated notepad and then open C:\Windows\system32\inetsrv\config\applicationHost.config.
  2. Search for adfs/ls and then delete the selected element below.image
  3. Save the file and you’ll be able to remove the application pool from IIS.

The service did not respond to the start or control request in a timely fashion.

$
0
0

When creating a new FS farm or joining a new node to an existing farm, i.e. running FSCONFIG.EXE or FSCONFIGWIZARD.EXE, or configuring an FS-P, i.e. running FSPCONFIGWIZARD.EXE, the process might fail with the resultant error being that the service did not respond to the start or control request in a timely fashion.

I have a screenshot from a simple script that is just a wrapper around FSCONFIG.  The output is from FSCONFIGs verbose switch.

clip_image002

As you can see everything succeeded except the service didn’t start quickly enough so the overall process fails.  If you try to start the the service it will start and all appears to be well.

The first couple of times I saw this issue was on VMs on my laptop.  I was writing a deployment guide and simply put it down to my machine being not exactly enterprise production class (five VMs, twenty instances of IE, a bunch of Word and Visio instances, Spotify, OneNote, etc. –you get the picture).  However I’ve now hit it in two different customer environments. 

Looks like the reason is related to the .NET Authenticode signature verification.  I’m not going to pretend I understand what all of this means to the CLR but after reading the remarks in the Publisher class documentation a couple of times the following seems to hold true:

  • Default behaviour within the .NET runtime is that code access security (CAS) does not check for Publisher evidence, therefore if you are not using a custom code group based on the PublisherMembershipCondition class, which AD FS binaries do not, disable Authenticode signature verification by configuring the runtime to not provide Publisher evidence for CAS and increase start up time.

How do we disable this?  Using the <generatePublisherEvidence> element of the Runtime settings schema (according to the aforementioned MSDN link).

This is actually already documented on the TechNet wiki.  Although for whatever reason I never stumbled upon this wiki article when searching for my error, hence this post.  I also feel I have a little more info. on the choices available to you –asking around my immediate community of AD FS folk and one or two .NET folk and it seems that the general consensus is that the better of the two options presented (turn off Authenticode signature verification or increase the Service Control Manager (SCM) timeout) is to disable Authenticode signature verification.  Obviously with this advice we assume that these are dedicated boxes, i.e. your FS is only an FS and not running a bunch of other managed code that might actually require the Publisher evidence!

And on this same subject a question I’ve fielded from two different customers is whether or not we implement this throughout the farm.  Your opinion on this matter might differ to mine but I like things to be consistent.  If I’m implementing a 2 x 2 farm (2 FS, 2 FS-P), for example, and I need to enable this setting on one node all nodes get it even if they succeeded.  I hate the idea of having multiple nodes in a farm with different configurations in place (other than those mandated on you like FIMs single point of failure -EWS polling- for example).

At this point my post is pretty much complete, however, even though I’ve liked you to the TechNet wiki I might as well define it here for completeness too.  To turn off Authenticode signature verification add the generatePublisherEvidence element with a property of enabled = FALSE to the .NET Framework runtime’s machine.config file:

Open \Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config from an elevated NOTEPAD and paste the following:

<configuration>
	<runtime>
		<generatepublisherevidence enabled="false" />
	</runtime>
</configuration>

In both of my cases there was an empty <runtime /> element that needs to be replaced by the above XML.  It was half way down underneath </configProtectedData> and above <connectionStrings>.


AD FS 329: The certificate that is identified by thumbprint ‘’ could not be decrypted using the keys for X.509 certificate private key sharing

$
0
0

Scenario

The Active Directory Federation Services (AD FS) 2.x service ADFSSRV will not start.  Event ID 329 is logged in the AD FS 2.0/Admin event log.  The pertinent text from event 329 is as follows:

Description:
The certificate that is identified by thumbprint ’041EB761382E43FF4232B1926DBA4FB4D62A2D86′ could not be decrypted using the keys for X.509 certificate private key sharing.

Additional Data:
X.509 certificate private key sharing diagnosis: MSIS7707: The container for X.509 certificate private key sharing with the distinguished name ‘CN=ADFS, CN=Microsoft, CN=Program Data, DC=domain-name, DC=com’ does not exist.

User Action
You may have to restore all Active Directory objects underneath the specified distinguished name in the diagnostic information above for X.509 certificate private key sharing.

Issue

When the AD FS service starts it looks for the certificate sharing objects underneath the ADFS container inside the Program Data/Microsoft container of the default domain.  The default domain is the domain that the service account is a member of.

The certificate sharing objects are created when you create the first node in the AD FS farm.  The FSCONFIG application retrieves the Program Data container from the default domain and creates the Microsoft/ADFS containers and the subsequent certificate sharing container and contact objects.  The default domain is the domain of the user performing the configuration, i.e. the user context running FSCONFIG.

The reason the service account cannot find the necessary container is because the service account is in a different domain to the account that created the farm and as such the certificate sharing information has been created in a different domain.

Note.

There are potentially different causes, such as accidental deletion of the container, accidental permissions change of the container, etc. however I have now seen this exact issue due to the service account and installation account residing in different domains in two customer environments and have reproduced in the lab, ergo this post.

Resolution

Uninstall AD FS, reinstall and run the farm configuration using an account (that is a member of domain admins, or has the necessary delegated permissions on the domain/Program Data/Microsoft container) in the same domain as the service account.  For example, if you have a root domain and three child domains with a relatively even distribution of users in the child domains you are likely installing AD FS on member servers in the root domain.  In this scenario ensure that the service account is in the root domain and that the user installing AD FS and/or performing the initial configuration is in the root domain.

Unfortunately I have not yet identified a supported way of remedying this issue without uninstalling and reinstalling.  Although that sounds like a massive endeavour it really isn’t if you have this issue for the reason described above, i.e. you have just installed and created your first FS farm node incorrectly.

If the farm was up and running and now you have this issue you have likely actually lost the container and/or contact objects and that requires a different fix, i.e. recovery from backup (authoritative restore).



AD FS 2.0 Issuance Authorization Rules: ensure two attributes match

$
0
0

I previously posted a couple of examples of AD FS 2.0 Issuance Authorization (AuthZ) Rules that I’ve used.  Troy posted a comment asking whether or not there is a way to ensure that two attributes match.  His specific example was can we only grant access if we can guarantee that UPN and e-mail are the same.

The short answer is yes, you can do this.  Although it wasn’t easy!  Smile

At first I figured we’d use a combination of exists and regex however that won’t work because there’s no way of injecting variables into the regex and if you did something like exists(Type = sometype, Value =~ someregex) && (Type = sometype, Value =~ someregex) that would match anything that matched the regex, e.g. paul@contoso.com and chuck@fabrikam.com.

My colleague Rahul Gangwar, an AD FS and WIF expert, pointed me in the right direction.  He said to use two rules.  One to create a temporary claim that is a concatenation and the second to parse it for equality.  How to deduce equality in a regex?  As I’ve already stated you can’t compare two values using the same regex and you can’t use repetition.  You can, however, use back-references.

So after several attempts, and thanks to the indispensable RegEx Builder, I finally worked out a regex that matches two e-mail addresses with a delimiter:

(?i)(^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4});\1

With the background described let’s look at how we achieve Troy’s ask.  We need two AuthZ rules:

  1. Concatenate
  2. Match

Here they are:

Concatenate equality values

c1:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"]
&& c2:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]
=> add(Type = “http://tmp/emailupn“, Value = c1.Value + “;” + c2.Value);

Compare values

c:[Type == "http://tmp/emailupn", Value =~ "(?i)(^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4});\1″]
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/permit”, Value = “true”);

The first rule, concatenate equality values, adds the UPN claim and the Email Address claim, delimited by a semi-colon, into a single temporary claim of the arbitrary type http://tmp/emailupn.

The second rule, compare values, issues a permit claim if the UPN and the e-mail address match.  The match is case-insensitive, i.e. paul.williams@contoso.com and Paul.Williams@contoso.com are the same.

Summary

I probably shouldn’t have used UPN and email as an example for this technique as it’s a bit of a tricky example.  But I wanted to address the comment.  After all, Troy was good enough to read my post and comment.  The approach is sound and can be used for other values too.  You just need to adopt the regex, e.g. (?i)(\w+);\1 would match any two words, so you could check two simple string values.  I think it wise to always perform a case-insensitive match via (?i) and let me give you a tip – don’t double escape like you would in C# or Java…


Update Rollup 3 for Active Directory Federation Services (AD FS) 2.0

$
0
0

Yesterday Microsoft released Update Rollup 3 for Active Directory Federation Services (AD FS) 2.0.

This update includes five (5) hotfixes, summarised below.  The update is cumulative which means it contains all fixes and features in the previous two updates: update rollup 1 and update rollup 2.

  1. AD FS 2.0 does not issue an ActAs token for a relying party who is using a Security Assertion Markup Language (SAML) 2.0 bootstrap token.
  2. AD FS 2.0 update rollup 2 introduced strict Uniform Resource Identifier (URI) checking. When AD FS 2.0 acts as a federation provider and trusts an identity provider whose identifier is not an URI, the response that is returned from the identity provider is rejected by AD FS 2.0. The validation fails because AD FS 2.0 tries to validate the value of the identity provider’s identifier. This behaviour breaks previously functioning AD FS 2.0 deployments in which identity providers use non-URI identifiers. AD FS 2.0 update rollup 3 removes this URI checking.
  3. AD FS 2.0 does not allow multiple relying party trusts to use the same signing certificate for SAML request.
    • Note that a post-installation/upgrade configuration task is required for this change to become effective.  The steps are described here.
  4. Performance of AD FS 2.0 needs improvement when HSM is used for storing private key of token signing/encryption certificate.
  5. AD FS 2.0 update rollup 1 introduces the Congestion Avoidance Algorithm. If you accidentally disable the Congestion Avoidance Algorithm by changing the configuration, a handle leak occurs on an AD FS 2.0 federation server proxy every time that the federation server proxy processes a request. AD FS 2.0 update rollup 3 removes the setting that enables you to disable Congestion Avoidance Algorithm by changing the configuration. You can fine tune the Congestion Avoidance Algorithm by adjusting the latencyThresholdInMsec and minCongestionWindowSize settings.

Uninstalling AD FS in Windows Server 2012

$
0
0

In my post Uninstalling AD FS 2.0 (and deleting the databases) I described how to uninstall AD FS 2.0 from Windows Server 2008 or 2008 R2.  While the process is fundamentally the same there are some subtle differences in Windows Server 2012 that mean the instructions in the previous post won’t work.  I felt I should post the differences and cover how to uninstall AD FS 2.1.

The two changes that tripped me up were the Windows Internal Database (WID) connection string and the location of the WID data files.  You connect to WID on Windows Server 2012 using the string:

\\.\pipe\MICROSOFT##WID\tsql\query

The default data file directory for WID on Windows Server 2012 is:

C:\Windows\WID\data

So you delete the AD FS database files using:

del C:\Windows\WID\data\adfs*

Otherwise the process is essentially the same:

  1. Retrieve the certificate sharing container (assuming you’re using auto certificate rollover feature)

    (Get-ADFSProperties).CertificateSharingContainer | clip
    
  2. Uninstall AD FS

    Remove-WindowsFeature adfs-federation
    
  3. Remove the databases from WID

    I downloaded SQL Server 2012 Express Management Tools to connect to WID and execute the T-SQL DML.

    • Connect:
      \\.\pipe\MICROSOFT##WID\tsql\query
    • Delete:
      use master;
      go
      sp_detach_db 'adfsconfiguration';
      go
      sp_detach_db 'adfsartifactstore';
      go
      
  4. Delete the data files

    del C:\Windows\WID\data\adfs*
    
  5. Uninstall WID

    Note that the name has changed in 2012. In Windows Server 2008/R2 the ServerManager name for WID was Windows-Internal-DB. In Windows Server 2012 it is Windows-Internal-Database!

    Remove-WindowsFeature windows-internal-database
    
  6. Clean-up IIS

    • Open IIS manager.  Expand <server> | Sites | Default Web Site | adfs
    • Right-click on ls and click Remove
    • Right-click on adfs and click Remove
    • Be sure to remove LS and then ADFS and don’t just remove ADFS otherwise you’ll be in the applicationHost.config deleting XML elements.
    • Click Application Pools (further up the tree) and right-click on ADFSAppPool and click Remove.
    • Lastly delete the folders and files.
      del c:\inetpub\adfs –Recurse
      
  7. Uninstall IIS?

    The previous task is not required if you uninstall IIS.

    Remove-WindowsFeature web-server
    
  8. Clean-up AD DS

    $delme = New-Object System.DirectoryServices.DirectoryEntry(
    "LDAP://CN=42bc22f5-e636-412f-9175-ba75912d4b4a,CN=ADFS,CN=Microsoft,CN=Program Data,DC=rnd,DC=litware-inc,DC=com")
    $delme.DeleteTree()
    

You can one-line that deletion too…

image

Check the previous post for a more thorough description.


Workplace Join failed 0x10dd (a.k.a. how to properly change/set your #ADFS certificates)

$
0
0

This post is really a simple layer-8 issue, but I thought it justified a post as there’s a nuance or two that are worth discussing.  I’m in the process of designing yet another Active Directory Federation Services deployment although this one is more interesting than some of my previous projects as it involves a lot of multi-factor authentication rules and configuration against a lot of trusts for a large user base.  While I’m authoring the design I like to essentially setup the design in my own lab, which is what brings me to this post.  I was enabling the Device Registration Services (DRS) in an existing Active Directory Federation Services (AD FS) 3.0 deployment and, having followed the small and simple set of well documented instructions, realised that my clients could not Workplace Join because the DRS essentially wasn’t there…

The WPJ event log on my Windows 7 desktop that is configured to automatically and silently WPJ showed this event:

image

And this:

image

Clicking that URL returns the browser “This page cannot be displayed” (as opposed to the actual XML when it works correctly) error.

Looks pretty clear.  There’s something really wrong with the DRS endpoint, i.e. it isn’t there (did I forget to enable DRS on each node?), or the DNS entry is wrong, etc.

So I take the URL and try hitting it on each local federation service server node (I have HOSTS entries on each node to hit self and avoid the internal load balancer).  The endpoint isn’t there.  No DNS issue, something else is up.  I dump the HTTP.SYS URLACL list (netsh http show urlacl) and I can see there’s a listener for this URL:

image

Rerunning Enable-ADFSDeviceRegistrationService doesn’t fix the matter.  It does complain about missing UPN suffixes but that’s expected as this is a multi-purpose lab and I have loads of UPN suffixes defined that won’t be used by WPJ clients.

image

I try hitting the https://enterpriseregistration.abstractsynapse.com/EnrollmentServer/contract?api-version=1.0 URL with the FS name instead, e.g.

https://federation.abstractsynapse.com/EnrollmentServer/contract?api-version=1.0 and that works.  I take a look at the certificate and the problem is now obvious.  This certificate doesn’t contain subject alternate name (SAN) properties.  Which is weird because I’ve just procured a new HTTPS certificate with multiple SAN properties to support DRS – as I said at the beginning, I was enabling DRS post-deployment.  My original deployment did not need DRS and therefore only had an SSL certificate with the FS name as the subject.  I have had to enrol a new certificate with multiple DNS SAN attributes for enterpriseregistration.<UPN suffix in use in the enterprise>.

And here’s the crux of the matter and the major layer-8 issue.  When I changed the AD FS certificate I did so using the following command on the primary FS:

Set-AdfsCertificate -CertificateType Service-Communications -Thumbprint “b5 9b d6 af 08 53 08 85 6e b8 aa 52 7b e3 15 65 87 66 e0 f5″

The problem is that command allows you to change the Service Communications certificate, the Token Signing certificate and the Token Encryption certificate.  That command does not change the SSL certificate!

To change the SSL certificate you must use Set-AdfsSslCertificate.  And unlike Set-AdfsCertificate you must do this on each FS node as it is configuring HTTP.SYS (we no longer do this in IIS).

image

Once done, the SAN attributes allow the HTTPS binding to work and the endpoint is live.  WPJ worked immediately then.

Lessons learned

When planning and designing AD FS consider future DRS needs.  Try and get the certificate right up front.  For many customers this is easy – they have a common and consistent UPN namespace, so just get the enterpriseregistration DNS SAN along with the DNS SAN for the FS name, e.g. for sts.contoso.com FS and users with @contoso.com UPN:

  • Subject: sts.contoso.com
  • SAN: DNS=sts.contoso.com
  • SAN: DNS=enterpriseregistration.contoso.com

For more complex deployments look to see what UPNs are in use.  In my experience DRS is closely aligned with cloud deployments and cloud deployments have a dependency on on-premises remediation that rationalises and remedies UPNs among other things.

When deploying the Device Registration Service, remember that the endpoints will only work if you have the correct DNS SAN attributes in your SSL certificate.  Check which certificate is in use using Get-AdfsSslCertificate and Get-AdfsCertificate -Type Service-Communications and also use the browser to validate, i.e. navigate to https://federation-service.domain-name.tld/federationmetadata/2007-06/federationmetadata.xml and look at the certificate in use by your browser – check the subject alternate name and subject fields and the thumbprint.

Lastly, deploying DRS consists of the following commands:

Primary FS (WID deployment):

  1. Initialize-ADDeviceRegistration (Initialise DRS in the AD DS forest – requires Enterprise Admins group membership)
  2. Enable-AdfsDeviceRegistration (Enable DRS on this server)
  3. Set-AdfsGlobalAuthenticationPolicy -DeviceAuthenticationEnabled $true (Enable device authentication in AD FS)

Secondary FS:

  1. Enable-AdfsDeviceRegistration (Enable DRS on this server)

In a SQL deployment you run the first set of commands on one node and the subsequent set of commands on all other nodes.

On your Web Application Proxy servers you might need to reconfigure the SSL endpoint listeners to listen on all of the SANs in your certificate.  You do this using Update-WebApplicationProxyDeviceRegistration.

Summary

When changing your AD FS SSL certificate remember you basically need to do this in two places for 99% of deployments:

  • You set the HTTPS certificate using Set-AdfsSslCertificate on each node in the farm
  • You set the Service Communications certificate using Set-AdfsCertificate on one server – in a WID deployment on the primary, in a SQL deployment on any node

You must also update your Web Application Proxy (WAP) servers, if they’re in play:

  • You set the HTTPS certificate for your WAP servers using the Set-WebApplicationProxySslCertificate cmdlet – again, as with Set-AdfsSslCertificate, this is done on each WAP node as it’s applying the configuration to HTTP.SYS
  • You update the HTTP.SYS endpoints using Update-WebApplicationProxyDeviceRegistration

This is important as the typical deployment pattern expects the service communications certificate to be the same as the federation service (SSL) certificate (it doesn’t have to be, hence the 99% of deployment statement). 

Note that even if you use the GUI you must remember to set the SSL certificate to correctly update the HTTP.SYS bindings.


AD FS, Enhanced Protection for Authentication (EPA), Chrome and Integrated Windows Authentication (IWA)

$
0
0

Something that I’ve had the misfortune of working on to look into recently was the user experience when accessing federated business apps using a browser that isn’t Internet Explorer.  Suffice to say, my customer has “two” supported browsers: IE (9, 10 and 11) and Chrome.  A number of apps, such as Office 365 and Salesforce.com don’t support IE9, however other apps require IE9.  Wonderful.  So Chrome has its place (and thankfully supports GPO, which is one of the reasons I’m a big IE fan).

In its default state, Windows Server 2012 R2 Active Directory Federation Services (AD FS) will only perform Integrated Windows Authentication (IWA) for Internet Explorer.  Other browsers will fall back to Forms Based Authentication (FBA) *if* FBA, and failback, is enabled in the global authentication policy.  This configuration is made possible through two AD FS configurations (three individual settings):

  • The Global Primary Authentication policy is configured for both Windows Authentication and Forms Authentication for the intranet (Set-AdfsGlobalAuthenticationPolicy -PrimaryIntranetAuthenticationProvider) and failback to FBA (Set-AdfsGlobalAuthenticationPolicy -WindowsIntegratedFallbackEnabled $true)
  • The global AD FS property (Set-AdfsProperties -WIASupportedUserAgents) contains regex patterns for various versions of IE

What does this mean?  Basically you enable FBA on the intranet and ensure that the property WindowsIntegratedFallbackEnabled is TRUE.  Then, any user agent not matching an element in the WIASupportedUserAgents property list will hit the FBA page even on the corporate network.  The experience is like the Internet/WAP experience.

As and when new browsers come along you have to carefully consider how to match those that work with IWA via the WIASupportedUserAgents property, e.g. you might choose to add the following elements to handle Edge and IE11:

  • Windows NT 10.0; WOW64; Trident/7.0
  • Edge/1

To handle other browsers, you need to match them.  Mozilla/5.0 will capture a slew of other browsers, including mobile devices, but if you expand that to:

  • Mozilla/5.0 (Windows NT

Then that will limit it to Firefox, Chrome and Opera running on a supported build of desktop Windows.  This is the approach I took.

That mitigates the UX issues whereby Chatter users, using Chrome, for example are faced with the “external/Internet experience” while on corpnet.  Everyone wants SSO on corpnet right?

The real problem comes with how these browsers react after you make this configuration change.

Firefox

Firefox first, as this works.  It prompts a rubbish IWA prompt, you enter your creds (DOMAIN\sAMAccountName or user.name@domain.tld) and you’re done.  To stop it prompting and actually do IWA like you’re used to with IE you configure the following properties with your domain, e.g. corp.contoso.com,concorp.com:

  • network.negotiate-auth.trusted-uris
  • network.automatic-ntlm-auth.trusted-uris

Having done that Firefox is done.  Hit an RP and behold SSO like IE gives you.

Here’s a screenshot of configuring those properties via about:config:

ePAFirefoxIWASettingsView

Safari, Opera, A. N. Other browser

I’m led to believe that Safari on a domain-joined Mac and Opera on Windows also work as expected (i.e. they can correctly handle IWA) but haven’t tested this myself.  Let me know if you see differently.

Chrome

Chrome on the other hand has an issue with Extended Protection for Authentication (EPA).  I’m not going to go off-topic and try and fully explain EPA, suffice to say that EPA is intended to increase the strength of the binding for the authentication when run over a Transport Layer Security (TLS) connection.  It mitigates a number of man in the middle (MITM) attacks and thus provides additional protection of browser-based authentication traffic.  More info.:

What is the issue?  Look to #43 in Chromium #270219 (https://code.google.com/p/chromium/issues/detail?id=270219):

Because Chrome doesn’t use Schannel for the SSL implementation it is not correctly implementing channel binding, thus Chrome cannot perform IWA when EPA is enabled (mandated) or allowed (optional).

What does this really mean?  It means you have to disable EPA within AD FS to support Chrome until the above bug is fixed and a stable released.

There’s plenty of info. about this around the place.  Basically that means setting the AD FS property ExtendedProtectionTokenCheck to None, e.g.

Set-AdfsProperties -ExtendedProtectionTokenCheck None

Here’s the KB: https://support.microsoft.com/en-us/kb/2461628

I felt that I needed to post something because the KB doesn’t give me enough.  This is quite specific to Chrome and the reason is a bug in Chrome not some issue in AD FS.  Firefox isn’t affected.  It’s also worth noting that the obvious answer isn’t to downgrade the security of the TLS session by simply disabling the ability to use CBTs.  For many the fall-back to FBA might be perfectly adequate.  This is only an issue if you use Chrome in the enterprise, want IWA and not FBA on corpnet and have configured AD FS to request IWA from non-IE browsers.

Additional information

For completeness, the TechNet article Configuring intranet forms-based authentication for devices that do not support WIA, currently (as of December 2015) lists the following user agent strings (which is a larger set than that that ships with AD FS):

Set-AdfsProperties -WIASupportedUserAgents @(
'MSIE 6.0',
'MSIE 7.0; Windows NT',
'MSIE 8.0',
'MSIE 9.0',
'MSIE 10.0; Windows NT 6',
'Windows NT 6.3; Trident/7.0',
'Windows NT 6.3; Win64; x64; Trident/7.0',
'Windows NT 6.3; WOW64; Trident/7.0',
'Windows NT 6.2; Trident/7.0',
'Windows NT 6.2; Win64; x64; Trident/7.0',
'Windows NT 6.2; WOW64; Trident/7.0',
'Windows NT 6.1; Trident/7.0',
'Windows NT 6.1; Win64; x64; Trident/7.0',
'Windows NT 6.1; WOW64; Trident/7.0',
'MSIPC',
'Windows Rights Management Client'
)

In my environments I actually implement the following:

Set-AdfsProperties -WIASupportedUserAgents @(
'MSIE 6.0',
'MSIE 7.0; Windows NT',
'MSIE 8.0',
'MSIE 9.0',
'MSIE 10.0; Windows NT 6',
'Windows NT 6.3; Trident/7.0',
'Windows NT 6.3; Win64; x64; Trident/7.0',
'Windows NT 6.3; WOW64; Trident/7.0',
'Windows NT 6.2; Trident/7.0',
'Windows NT 6.2; Win64; x64; Trident/7.0',
'Windows NT 6.2; WOW64; Trident/7.0',
'Windows NT 6.1; Trident/7.0',
'Windows NT 6.1; Win64; x64; Trident/7.0',
'Windows NT 6.1; WOW64; Trident/7.0',
'MSIPC',
'Windows Rights Management Client',

'Windows NT 10.0; WOW64; Trident/7.0',
'Edge/1',
'Mozilla/5.0 (Windows NT'
)

…and one more thing

I promised my colleague John that I wouldn’t rant about the whole WIA vs. IWA nomenclature clash.  So I won’t.  But I’ll end the post with this question: what were the AD FS product group thinking?  (The correct and true acronym is IWA and has been for years!) :) :)

Summary

If you want to support non-IE browsers enable FBA on the intranet authentication provider and enable fallback to FBA, e.g.

Set-AdfsGlobalAuthenticationPolicy -PrimaryIntranetAuthenticationProvider @( 'WindowsAuthentication', 'FormsAuthentication' ) -WindowsIntegratedFallbackEnabled $true

If you want to enable some of these browsers to not perform FBA and work in the same way as IE, i.e. SSO using IWA, then you need to pick an appropriate user agent string and add it to the WIASupportedUserAgents property, as illustrated above using Set-AdfsProperties -WIASupportedUserAgents

If you want to use IWA to SSO to AD FS using Chrome you will need to disable EPA in the short term until Google fix Chrome.  Long term you should look to turn EPA on and make use of CBT.

 


AD FS 2.0 Issuance Authorization Rules

$
0
0

I had to create a couple of issuance authorization rules in my last engagement and it took me a little longer than it should have to get the syntax correct so I thought I’d post a couple of examples that might be of interest to others.

Firstly, lets clarify what I’m talking about.  Taken from When to Use an Authorization Claim Rule in the AD FS 2.0 Design Guide:

You can use this rule in Active Directory Federation Services (AD FS) 2.0 when you need to take an incoming claim type and then apply an action that will determine whether a user will be permitted or denied access based on the value that you specify in the rule. When you use this rule, you pass through or transform claims that match the following rule logic, based on either of the options you configure in the rule:

To wrap some further context around this post you define issuance authorization rules on relying party trusts.  These rules are applied early on in the claims pipeline process.  You use issuance authorization rules to determine whether or not a user has access to an relying party application. 

A common issuance authorization rule is the permit access to all users rule template.  If you look at the underlying claim rule language for this template you will see the following:

=> issue(Type = “http://schemas.microsoft.com/authorization/claims/permit&#8221;, Value = “true”);

Nice and easy.  Issue a claim of the type http://schemas.microsoft.com/authorization/claims/permit with a value of true. 

It’s worth pointing out here that the value is irrelevant.  The authorisation engine only looks for the type of claim, allowing access if there is a claim with a type of http://schemas.microsoft.com/authorization/claims/permit, and not allowing access if there’s no permit claim type or if there is a claim with a type of  http://schemas.microsoft.com/authorization/claims/deny present.  More information on this here.

The purpose of this post is to share two simple examples.  I just designed an AD FS solution and made use of authorization rules to achieve the requirement of all users in domain-a have access to RP application XYZ.  In this environment there were three domains in the forest.  We only wanted users in one of the domains to access the application.  I achieved this by creating a rule with the Send Claims Using a Custom Rule template and the following rule:

c:[Type == “http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname&#8221;, Value =~ “^(?i)CORP\\.+$”]
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/permit&#8221;, Value = “true”);

To explain the rule lets assume we have the following domains in the forest: corp.contoso.com, partner.contoso.com, and emea.corp.contoso.com.  The above claim rule only permits access to a relying party if the Windows account name (http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname) claim type has a value of CORP\something, e.g. CORP\paulw or CORP\chucn.

Next we had a similar requirement that we achieved with a rule around the value of the UPN claim type.  We wanted partners to be able to access an RP.  Non-employee accounts in the directory had a different UPN suffix to employees and contractors (non-employee accounts are created in partner.contoso.com if the partner organisation doesn’t have federation infrastructure).  In this scenario we decided to permit access to an RP application for all users with a UPN of something@partner.contoso.com.  Here’s an example:

c:[Type == “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn&#8221;, Value =~ “^(?i).+@partner\.contoso\.com$”]
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/permit&#8221;, Value = “true”);

Hopefully this will help someone.  It took me longer than it should have to get the regex right.  Smile

Just in case you need a little more guidance on how to create these rules…

If you’re new to AD FS and have just read the above and are thinking awesome, I really want to use that UPN rule but…I have no idea how to create it here goes…

  1. Open AD FS 2.0 management console, click Relying Party Trusts, click the RP trust that you want to configure and click Edit Claim Rules… in the actions bar.
  2. The Edit Claim Rules for <RP name> dialog opens.  Click the Issuance Authorization Rules tab (the middle tab).  If you’re accessing the RP presently you likely have a single rule called Permit Access to All Users with an issued claims of Permit in the list.  Remove this rule and click Add Rule…
  3. Choose the Send Claims Using a Custom Rule template and click Next.
  4. Supply a name and then paste your syntax into the custom rule input.  Click Finish.

If you consider the following rule:

c:[Type == “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn&#8221;, Value =~ “^(?i).+@partner\.contoso\.com$“]
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/permit&#8221;, Value = “true”);

The part that you need to configure is the regex –the contents within the quotes after =~ e.g. ^(?i).+@partner\.contoso\.com$.

Regarding the regex.

  • (?i) makes the pattern case insensitive.
  • ^ means starts with.
  • .+ means anything one or more times.
  • @partner\.contoso\.com is the URL with an escape sequence for the dot (or period).
  • $ means ends with.

Uninstalling AD FS 2.0 (and deleting the databases)

$
0
0

**This post was written for AD FS 2.0 running on Windows Server 2008 or Windows Server 2008 R2.  For information on uninstalling and cleaning up AD FS 2.1 on Windows Server 2012 please see the post Uninstalling AD FS in Windows Server 2012.

I’ve been working on an installation guide for AD FS 2.0 and have needed to uninstall and reinstall several times.  When you uninstall AD FS the database isn’t deleted.  The IIS applications aren’t removed and the token signing objects in AD DS aren’t removed.  Microsoft Support knowledgebase article kb982813 How to restore IIS and clean up Active Directory when you uninstall Active Directory Federation Services 2.0 describes how to remove the AD DS objects and the IIS applications and virtual directories but does not explain how to remove the AD FS database.  This isn’t a major problem as the FsConfig.exe configuration tool has a /cleanconfig switch that will drop and create new databases however when you’re developing guidance for others you can’t really use the CLEAN switch and therefore need to be able to effectively remove the database.  The following instructions explain how to do this.  AD FS 2.0: Migrate Your AD FS Configuration Database to SQL Server was the guiding factor in putting this post together.

Here’s what I had to do and did.

Note.

If you are following these instructions and still have a working AD FS skim down to the clean up AD DS section and perform those steps first.

Uninstall AD FS 2.0

  1. Open APPWIZ.CPL.
  2. Click View Installed Updates and type ACTIVE into the Search Programs and Features search bar.
  3. Select Active Directory Federation Services 2.0 and click Uninstall.

Remove databases from WID

  1. Downloaded and installed SQL Server 2008 R2 Express Management Tools.
  2. Using SQL Server Management Studio (SSMS) connected to:
    \\.\pipe\MSSQL$MICROSOFT##SSEE\sql\query
  3. Executed the following T-SQL script:
    use master;
    go
    sp_detach_db 'adfsconfiguration';
    go
    sp_detach_db 'adfsartifactstore';
    go
    
  4. When complete I deleted the data files:
    del C:\Windows\SYSMSI\SSEE\MSSQL.2005\MSSQL\Data\adfs*

Uninstall WID

Lastly, you can remove WID using Server Manager, e.g.

Import-Module ServerManager
Get-WindowsFeature | ? {
    $_.Installed -and
    $_.Name -eq 'Windows-Internal-DB'
} | Remove-WindowsFeature

Clean up and uninstall IIS

Next you need to clean up IIS as per kb982813:

  1. Open IIS manager.  Expand <server> | Sites | Default Web Site | adfs
  2. Right-click on ls and click Remove
  3. Right-click on adfs and click RemoveBe sure to remove LS and then ADFS and don’t just remove ADFS otherwise you’ll be in the applicationHost.config deleting XML elements.
  4. Click Application Pools (further up the tree) and right-click on ADFSAppPool and click Remove.
  5. Lastly delete the folders and files.
    Remove-Item C:\inetpub\adfs -Recurse

Clean up AD DS

Ideally this step is first –then you can do this:

Add-PSSnapin microsoft.adfs.powershell
(Get-ADFSProperties).CertificateSharingContainer

Which gives you the DN, e.g.

image

But more often than not we read the instructions last.  So we need to delete the container with a CN of the GUID of your AD FS farm from CN=Microsoft, CN=Program Data, DC=your-domain, DC=tld.

image

In the case of the above picture I’ve stood up and torn down five AD FS farms.  All of these certificate sharing containers need to go.  But you need to be careful here.  Please be sure there aren’t other active AD FS farms in the domain before you delete them!

And regarding deleting, I’m a big user of LDP but also like PowerShell and often don’t have access to ADWS (Active Directory Web Services) so here’s a little snippet for delete using S.DS (System.DirectoryServices).

$delme = New-Object System.DirectoryServices.DirectoryEntry(
    "LDAP://CN=42bc22f5-e636-412f-9175-ba75912d4b4a,CN=ADFS,CN=Microsoft,CN=Program Data,DC=rnd,DC=litware-inc,DC=com")
$delme.DeleteTree()

Wrap-up

At this point all should be removed and all well.  If you deleted the ADFS application before you deleted the LS application read on.  I hope this post has been helpful!

Application pool ‘ADFSAppPool’ cannot be deleted because it contains 1 applications

If you got the order wrong and you get the error: “Application pool ‘ADFSAppPool’ cannot be deleted because it contains 1 applications.” (dialog below) you need to perform the following steps.

image

  1. Open an elevated notepad and then open C:\Windows\system32\inetsrv\config\applicationHost.config.
  2. Search for adfs/ls and then delete the selected element below.image
  3. Save the file and you’ll be able to remove the application pool from IIS.


The service did not respond to the start or control request in a timely fashion.

$
0
0

When creating a new FS farm or joining a new node to an existing farm, i.e. running FSCONFIG.EXE or FSCONFIGWIZARD.EXE, or configuring an FS-P, i.e. running FSPCONFIGWIZARD.EXE, the process might fail with the resultant error being that the service did not respond to the start or control request in a timely fashion.

I have a screenshot from a simple script that is just a wrapper around FSCONFIG.  The output is from FSCONFIGs verbose switch.

clip_image002

As you can see everything succeeded except the service didn’t start quickly enough so the overall process fails.  If you try to start the the service it will start and all appears to be well.

The first couple of times I saw this issue was on VMs on my laptop.  I was writing a deployment guide and simply put it down to my machine being not exactly enterprise production class (five VMs, twenty instances of IE, a bunch of Word and Visio instances, Spotify, OneNote, etc. –you get the picture).  However I’ve now hit it in two different customer environments. 

Looks like the reason is related to the .NET Authenticode signature verification.  I’m not going to pretend I understand what all of this means to the CLR but after reading the remarks in the Publisher class documentation a couple of times the following seems to hold true:

  • Default behaviour within the .NET runtime is that code access security (CAS) does not check for Publisher evidence, therefore if you are not using a custom code group based on the PublisherMembershipCondition class, which AD FS binaries do not, disable Authenticode signature verification by configuring the runtime to not provide Publisher evidence for CAS and increase start up time.

How do we disable this?  Using the <generatePublisherEvidence> element of the Runtime settings schema (according to the aforementioned MSDN link).

This is actually already documented on the TechNet wiki.  Although for whatever reason I never stumbled upon this wiki article when searching for my error, hence this post.  I also feel I have a little more info. on the choices available to you –asking around my immediate community of AD FS folk and one or two .NET folk and it seems that the general consensus is that the better of the two options presented (turn off Authenticode signature verification or increase the Service Control Manager (SCM) timeout) is to disable Authenticode signature verification.  Obviously with this advice we assume that these are dedicated boxes, i.e. your FS is only an FS and not running a bunch of other managed code that might actually require the Publisher evidence!

And on this same subject a question I’ve fielded from two different customers is whether or not we implement this throughout the farm.  Your opinion on this matter might differ to mine but I like things to be consistent.  If I’m implementing a 2 x 2 farm (2 FS, 2 FS-P), for example, and I need to enable this setting on one node all nodes get it even if they succeeded.  I hate the idea of having multiple nodes in a farm with different configurations in place (other than those mandated on you like FIMs single point of failure -EWS polling- for example).

At this point my post is pretty much complete, however, even though I’ve liked you to the TechNet wiki I might as well define it here for completeness too.  To turn off Authenticode signature verification add the generatePublisherEvidence element with a property of enabled = FALSE to the .NET Framework runtime’s machine.config file:

Open \Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config from an elevated NOTEPAD and paste the following:

<configuration>
	<runtime>
		<generatepublisherevidence enabled="false" />
	</runtime>
</configuration>

In both of my cases there was an empty <runtime /> element that needs to be replaced by the above XML.  It was half way down underneath </configProtectedData> and above <connectionStrings>.


AD FS 329: The certificate that is identified by thumbprint ‘’ could not be decrypted using the keys for X.509 certificate private key sharing

$
0
0

Scenario

The Active Directory Federation Services (AD FS) 2.x service ADFSSRV will not start.  Event ID 329 is logged in the AD FS 2.0/Admin event log.  The pertinent text from event 329 is as follows:

Description:
The certificate that is identified by thumbprint ‘041EB761382E43FF4232B1926DBA4FB4D62A2D86’ could not be decrypted using the keys for X.509 certificate private key sharing.

Additional Data:
X.509 certificate private key sharing diagnosis: MSIS7707: The container for X.509 certificate private key sharing with the distinguished name ‘CN=ADFS, CN=Microsoft, CN=Program Data, DC=domain-name, DC=com’ does not exist.

User Action
You may have to restore all Active Directory objects underneath the specified distinguished name in the diagnostic information above for X.509 certificate private key sharing.

Issue

When the AD FS service starts it looks for the certificate sharing objects underneath the ADFS container inside the Program Data/Microsoft container of the default domain.  The default domain is the domain that the service account is a member of.

The certificate sharing objects are created when you create the first node in the AD FS farm.  The FSCONFIG application retrieves the Program Data container from the default domain and creates the Microsoft/ADFS containers and the subsequent certificate sharing container and contact objects.  The default domain is the domain of the user performing the configuration, i.e. the user context running FSCONFIG.

The reason the service account cannot find the necessary container is because the service account is in a different domain to the account that created the farm and as such the certificate sharing information has been created in a different domain.

Note.

There are potentially different causes, such as accidental deletion of the container, accidental permissions change of the container, etc. however I have now seen this exact issue due to the service account and installation account residing in different domains in two customer environments and have reproduced in the lab, ergo this post.

Resolution

Uninstall AD FS, reinstall and run the farm configuration using an account (that is a member of domain admins, or has the necessary delegated permissions on the domain/Program Data/Microsoft container) in the same domain as the service account.  For example, if you have a root domain and three child domains with a relatively even distribution of users in the child domains you are likely installing AD FS on member servers in the root domain.  In this scenario ensure that the service account is in the root domain and that the user installing AD FS and/or performing the initial configuration is in the root domain.

Unfortunately I have not yet identified a supported way of remedying this issue without uninstalling and reinstalling.  Although that sounds like a massive endeavour it really isn’t if you have this issue for the reason described above, i.e. you have just installed and created your first FS farm node incorrectly.

If the farm was up and running and now you have this issue you have likely actually lost the container and/or contact objects and that requires a different fix, i.e. recovery from backup (authoritative restore).


AD FS 2.0 Issuance Authorization Rules: ensure two attributes match

$
0
0

I previously posted a couple of examples of AD FS 2.0 Issuance Authorization (AuthZ) Rules that I’ve used.  Troy posted a comment asking whether or not there is a way to ensure that two attributes match.  His specific example was can we only grant access if we can guarantee that UPN and e-mail are the same.

The short answer is yes, you can do this.  Although it wasn’t easy!  Smile

At first I figured we’d use a combination of exists and regex however that won’t work because there’s no way of injecting variables into the regex and if you did something like exists(Type = sometype, Value =~ someregex) && (Type = sometype, Value =~ someregex) that would match anything that matched the regex, e.g. paul@contoso.com and chuck@fabrikam.com.

My colleague Rahul Gangwar, an AD FS and WIF expert, pointed me in the right direction.  He said to use two rules.  One to create a temporary claim that is a concatenation and the second to parse it for equality.  How to deduce equality in a regex?  As I’ve already stated you can’t compare two values using the same regex and you can’t use repetition.  You can, however, use back-references.

So after several attempts, and thanks to the indispensable RegEx Builder, I finally worked out a regex that matches two e-mail addresses with a delimiter:

(?i)(^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4});\1

With the background described let’s look at how we achieve Troy’s ask.  We need two AuthZ rules:

  1. Concatenate
  2. Match

Here they are:

Concatenate equality values

c1:[Type == “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn“]
&& c2:[Type == “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress“]
=> add(Type = “http://tmp/emailupn“, Value = c1.Value + “;” + c2.Value);

Compare values

c:[Type == “http://tmp/emailupn”, Value =~ “(?i)(^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4});\1”]
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/permit”, Value = “true”);

The first rule, concatenate equality values, adds the UPN claim and the Email Address claim, delimited by a semi-colon, into a single temporary claim of the arbitrary type http://tmp/emailupn.

The second rule, compare values, issues a permit claim if the UPN and the e-mail address match.  The match is case-insensitive, i.e. paul.williams@contoso.com and Paul.Williams@contoso.com are the same.

Summary

I probably shouldn’t have used UPN and email as an example for this technique as it’s a bit of a tricky example.  But I wanted to address the comment.  After all, Troy was good enough to read my post and comment.  The approach is sound and can be used for other values too.  You just need to adopt the regex, e.g. (?i)(\w+);\1 would match any two words, so you could check two simple string values.  I think it wise to always perform a case-insensitive match via (?i) and let me give you a tip – don’t double escape like you would in C# or Java…


Update Rollup 3 for Active Directory Federation Services (AD FS) 2.0

$
0
0

Yesterday Microsoft released Update Rollup 3 for Active Directory Federation Services (AD FS) 2.0.

This update includes five (5) hotfixes, summarised below.  The update is cumulative which means it contains all fixes and features in the previous two updates: update rollup 1 and update rollup 2.

  1. AD FS 2.0 does not issue an ActAs token for a relying party who is using a Security Assertion Markup Language (SAML) 2.0 bootstrap token.
  2. AD FS 2.0 update rollup 2 introduced strict Uniform Resource Identifier (URI) checking. When AD FS 2.0 acts as a federation provider and trusts an identity provider whose identifier is not an URI, the response that is returned from the identity provider is rejected by AD FS 2.0. The validation fails because AD FS 2.0 tries to validate the value of the identity provider’s identifier. This behaviour breaks previously functioning AD FS 2.0 deployments in which identity providers use non-URI identifiers. AD FS 2.0 update rollup 3 removes this URI checking.
  3. AD FS 2.0 does not allow multiple relying party trusts to use the same signing certificate for SAML request.
    • Note that a post-installation/upgrade configuration task is required for this change to become effective.  The steps are described here.
  4. Performance of AD FS 2.0 needs improvement when HSM is used for storing private key of token signing/encryption certificate.
  5. AD FS 2.0 update rollup 1 introduces the Congestion Avoidance Algorithm. If you accidentally disable the Congestion Avoidance Algorithm by changing the configuration, a handle leak occurs on an AD FS 2.0 federation server proxy every time that the federation server proxy processes a request. AD FS 2.0 update rollup 3 removes the setting that enables you to disable Congestion Avoidance Algorithm by changing the configuration. You can fine tune the Congestion Avoidance Algorithm by adjusting the latencyThresholdInMsec and minCongestionWindowSize settings.

Uninstalling AD FS in Windows Server 2012

$
0
0

In my post Uninstalling AD FS 2.0 (and deleting the databases) I described how to uninstall AD FS 2.0 from Windows Server 2008 or 2008 R2.  While the process is fundamentally the same there are some subtle differences in Windows Server 2012 that mean the instructions in the previous post won’t work.  I felt I should post the differences and cover how to uninstall AD FS 2.1.

The two changes that tripped me up were the Windows Internal Database (WID) connection string and the location of the WID data files.  You connect to WID on Windows Server 2012 using the string:

\\.\pipe\MICROSOFT##WID\tsql\query

The default data file directory for WID on Windows Server 2012 is:

C:\Windows\WID\data

So you delete the AD FS database files using:

del C:\Windows\WID\data\adfs*

Otherwise the process is essentially the same:

  1. Retrieve the certificate sharing container (assuming you’re using auto certificate rollover feature)

    (Get-ADFSProperties).CertificateSharingContainer | clip
    
  2. Uninstall AD FS

    Remove-WindowsFeature adfs-federation
    
  3. Remove the databases from WID

    I downloaded SQL Server 2012 Express Management Tools to connect to WID and execute the T-SQL DML.

    • Connect:
      \\.\pipe\MICROSOFT##WID\tsql\query
    • Delete:
      use master;
      go
      sp_detach_db 'adfsconfiguration';
      go
      sp_detach_db 'adfsartifactstore';
      go
      
  4. Delete the data files

    del C:\Windows\WID\data\adfs*
    
  5. Uninstall WID

    Note that the name has changed in 2012. In Windows Server 2008/R2 the ServerManager name for WID was Windows-Internal-DB. In Windows Server 2012 it is Windows-Internal-Database!

    Remove-WindowsFeature windows-internal-database
    
  6. Clean-up IIS

    • Open IIS manager.  Expand <server> | Sites | Default Web Site | adfs
    • Right-click on ls and click Remove
    • Right-click on adfs and click Remove
    • Be sure to remove LS and then ADFS and don’t just remove ADFS otherwise you’ll be in the applicationHost.config deleting XML elements.
    • Click Application Pools (further up the tree) and right-click on ADFSAppPool and click Remove.
    • Lastly delete the folders and files.
      del c:\inetpub\adfs –Recurse
      
  7. Uninstall IIS?

    The previous task is not required if you uninstall IIS.

    Remove-WindowsFeature web-server
    
  8. Clean-up AD DS

    $delme = New-Object System.DirectoryServices.DirectoryEntry(
    "LDAP://CN=42bc22f5-e636-412f-9175-ba75912d4b4a,CN=ADFS,CN=Microsoft,CN=Program Data,DC=rnd,DC=litware-inc,DC=com")
    $delme.DeleteTree()
    

You can one-line that deletion too…

image

Check the previous post for a more thorough description.


Viewing all 26 articles
Browse latest View live