Category Archives: AD FS 2.0

AD FS – Old Habits (idpinitiatedsignon.aspx)

Usually after building an AD FS/WAP farm I test locally from the Internet and the Intranet using (to-date) a fairly reliable source of verification that the service is up and running. I’m referring to, of course, the IdP sign-in page (../adfs/ls/idpinitiatedsignon.aspx). This offers a simple way of validating login via AD FS.

With Windows Server 2016, this page is no longer surfaced “out-of-the-box”.. if you want to do a SAML 2.0  IdP-initiated sign-on, this functionality will need to be enabled. Otherwise, connecting to the obligatory sign-in page, will produce an error similar to the following:

2016-06-10_18-06-00

Testing from the Web Application Proxy itself directly,  pointing to the AD FS farm, we may see an HTTP 503 Service Not Available error.

Via Powershell, it can be switched back on:

set-adfsproperties -EnableIdpInitiatedSignon $True

Now, before we get too hasty,  knowing that we can turn it back on versus actually turning it back on are two different things 🙂 If it’s directly required, IdP-driven sign-on is a feature of your federation setup, then you may have no choice. For example, certain SaaS/Cloud applications simply don’t support SP-initiated workflow.

For some organizations I’ve worked for though, this page is seen as insidious because it reveals the relying parties configured on your AD FS farm anonymously.

AD FS 2.0

2016-06-16_18-57-06

AD FS 2012 R2

2016-06-16_18-58-34

Going back to AD FS 2.0, customers are often unwilling to float this data anonymously via the sign-in page and want to hide the RP enabled trusts visible on the page, sometimes re-writing the code behind to do so or even hiding it from the browser via obfuscation.

Whatever your view, it’s off by default in Windows Server 2016. Those of a paranoid bent may now breathe …………. in….. out….in… out…. there you go 🙂

 

 

Interoperability scenarios with simpleSAMLphp and AD FS

 

Hello all and Happy New Year!

In this post we’ll look at inter-operability scenarios involving simpleSAMLphp and Active Directory Federation Services (AD FS).

simpleSAMLphp is a native PHP application that provides support for a number of authentication protocols/methods. Its origins lie with the SAML protocol, but it also provides support for a range of other authentication protocols (e.g. WS-Federation, OAuth, LDAP, RADIUS).  It’s a very capable and robust platform that can run on a number of different web surfaces.

In this post we’ll be covering identity federation scenarios with simpleSAMLphp and our usual incumbent: AD FS, getting the two to play nicely together.  We’ll look at both sides of the coin via a:

(a)    simpleSAMLphp Service Provider (SP) / AD FS Identity Provider (IdP) pairing.

(b)   simpleSAMLphp Identity Provider (IdP) / AD FS Service Provider (SP) pairing;

 

In both cases, setup is applicable to both AD FS 2.0 and AD FS 3.0/2012 R2.

For an introduction to simpleSAMLphp, start here.  It runs on a wide variety of web servers (Apache, Nginx, IIS among others).  In these scenarios we’ll use IIS as our web server for deployment.

clip_image002

The latest PHP libraries can be obtained through the IIS Web Platform Installer. In this setup PHP 5.5.x is used and simpleSAMLphp 1.13.x.

The latest binaries for simpleSAMLphp are available via their website (http://www.simplesamlphp.org).

For SAML integration with AD FS, SSL certificate(s) are required to secure the IIS website(s) and the underlying simpleSAMLphp application(s). This pre-requisite stems from AD FS supporting HTTPS only.  In the test configuration described here, the simpleSAMLphp instances are also published behind an AD FS Web Application Proxy (WAP). The pass-through (reverse) proxy functions of the WAP are then used to publish the simpleSAMLphp IdP/SP endpoints.  On the IIS side, Server Name Indication (SNI) is also enabled. 

The test setup used here comprises four virtual machines:

(i)                  An Active Directory Domain Services (AD DS) and Certificate Services (AD CS) node;

(ii)                An Active Directory Federation Services (AD FS) 2012 R2 Farm node;

(iii)               A Web Application Proxy (WAP) 2012 R2 node;

(iv)              An IIS 8.5 Web server with php loaded as an application. This hosts the simpleSAMLphp Identity Provider (IdP), Service Provider and test applications, under dedicated websites/paths.

clip_image004

The AD DS and AD CS instances provide authentication and the SSL certificates for the IIS web services. On the Web Application Proxy (WAP) a third-party certificate is installed. This goes somewhat against the grain with Microsoft recommendations of using the same certificate pairing on the WAP and AD FS. However, since we’re not using device management/Workplace Join in this scenario, which I believe the requirements stem from, there are no immediate issues.

On our “application server” IIS is installed. Herein, I’ve created four websites (idp1, idp2, site1 and site2), representing two simpleSAMLphp SAML 2.0 identity providers and two simpleSAMLphp service providers. The website configuration can be seen in the below graphic:

clip_image005

In each case the simpleSAMLphp files are unzipped to a folder per function, e.g:

·         c:\inetpub\idp1 and c:\inetpub\idp2 for the SAML identity provider (IdP) root paths

·         c:\inetpub\web1 and c:\inetpub\web2 for the SAML server provider (SP) root paths

In IIS Manager, we can see the folder structure of an exploded simpleSAMLphp configuration for a single instance.

clip_image006

In each instance, under the config folder, a baseurlpath setting in the config.php file is set to indicate the root path for simpleSAMLphp content. By default, this is set to www.  Should we wish to change this, such that the desired path to our simpleSAMLphp is say https://idp1.mydomain.com/auth  rather than the default https://idp1.mydomain.com/www, then we make the change to the baseurlpath from ‘www/’ to auth/ and rename the www folder accordingly. Note the use of the trailing slash that should always be present in the  baseurlpath value.

From a simpleSAMLphp standpoint, there’s a few tweaking steps required before we get going in our test setup.

By default, a secretsalt setting is configured in the config.php file and it’s strongly recommended to change this. This should be a random string, as the salt is used to generate cryptographically secure hashes.

Also, we should consider getting logging working properly. This will reap dividends later when it comes to troubleshooting. As with other settings so far mentioned, logging settings are defined in config.php.

Firstly, debug is enabled via setting:                               

‘debug’ => TRUE,

By default, the logging level is set to SYSLOG.  Here we’ll also switch the logging level to DEBUG and then alter the handler to file. This is done by setting the following values:

     ‘logging.level’         => SimpleSAML_Logger::DEBUG,

       ‘logging.handler’       => ‘file’,

 

In later sections of the CONFIG.PHP file, the output filename is also specified. This writes to the log folder of the instance.

‘logging.logfile’          => ‘simpleSAMLphp.log’,

This log file lives under the /log folder of the simpleSAMLphp instance. However, simply specifying the file to use is not sufficient for logging under IIS to work.   For that little feat, the IUSR needs to been given modify access to the simpleSAMLphp logfile.

clip_image008

Repeat this process for each instance of simpleSAMLphp running under IIS on your server(s), giving the IUSR account the appropriate permissions.

Once logging has been configured, we can see the benefits of verbose logging as it provides a rich level of detail. Here’s a sample:

<AttributeStatement>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]       <Attribute xmlns:a=”http://schemas.xmlsoap.org/ws/2009/09/identity/claims&#8221; Name=”http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-ip&#8221; a:OriginalIssuer=”CLIENT CONTEXT”>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]         <AttributeValue>172.16.x.6</AttributeValue>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]       </Attribute>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]       <Attribute xmlns:a=”http://schemas.xmlsoap.org/ws/2009/09/identity/claims&#8221; Name=”http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip&#8221; a:OriginalIssuer=”CLIENT CONTEXT”>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]         <AttributeValue>212.x.y.5</AttributeValue>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]       </Attribute>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]       <Attribute xmlns:a=”http://schemas.xmlsoap.org/ws/2009/09/identity/claims&#8221; Name=”http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork&#8221; a:OriginalIssuer=”CLIENT CONTEXT”>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]         <AttributeValue xmlns:tn=”http://www.w3.org/2001/XMLSchema&#8221; xmlns:b=”http://www.w3.org/2001/XMLSchema-instance&#8221; b:type=”tn:boolean”>false</AttributeValue>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]       </Attribute>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]       <Attribute xmlns:a=”http://schemas.xmlsoap.org/ws/2009/09/identity/claims&#8221; Name=”http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path&#8221; a:OriginalIssuer=”CLIENT CONTEXT”>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]         <AttributeValue>/adfs/ls/</AttributeValue>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]       </Attribute>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]       <Attribute xmlns:a=”http://schemas.xmlsoap.org/ws/2009/09/identity/claims&#8221; Name=”http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-user-agent&#8221; a:OriginalIssuer=”CLIENT CONTEXT”>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]         <AttributeValue>Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; WOW64; Trident/7.0; Touch; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; Tablet PC 2.0; InfoPath.3; MASEJS)</AttributeValue>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]       </Attribute>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]       <Attribute xmlns:a=”http://schemas.xmlsoap.org/ws/2009/09/identity/claims&#8221; Name=”uid” NameFormat=”urn:oasis:names:tc:SAML:2.0:attrname-format:basic” a:OriginalIssuer=”https://idp1.mylos.net/www/saml2/idp/metadata.php”&gt;

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]         <AttributeValue>student</AttributeValue>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]       </Attribute>

Sep 19 17:30:19 simpleSAMLphp DEBUG [5805446797]     </AttributeStatement>

 

Back in IIS, I’ve elected to employ the services of our friend Server Name Indication (SNI). This is defined on the website. Unlike with AD FS, SNI is an option under IIS J

clip_image010

 

SNI allows us to run multiple web sites under IIS, using different certificates/domain combinations per website, all bound to a shared single IP address. This makes it possible in this test setup to run with numerous instances of simpleSAMLphp, in identity and service provider roles, all on the same server; without having to deal with the hassle of SSL Host Headers, listener changes, tweaking friendly names on certificates etc.

Web server setup itself is pretty straightforward. For simpleSAMLphp instances, either identity or service provider, we prep the web server with the following steps:

    1. create an A record for the URL in AD DNS, e.g. idp1.mydomain.com
    2. create an A record for the URL in Internet/External  DNS and point this to the IP address/VIP of the Web Application Proxy.
    3. create a website in IIS for simpleSAMLphp and point the configuration to the baseurlpath, of your choice, e.g. c:\inetpub\wwwroot\idp1\www
    4. add an SSL binding on the website, with Require Server Name Indication (SNI) enabled and a host header matching the URL, e.g. idp1.mydomain.com
    5. publish the new website on the reverse proxy (Web Application Proxy) using a pass-through rule
    6. configure the simpleSAMLphp configuration as described later in the post
    7. repeat for each additional new instance

Web Application Proxy (Optional)

In this lab, we’re using the AD FS Web Application Proxy (WAP) to reverse proxy HTTPS traffic to the various simpleSAMLphp endpoints. The following pass-through proxy rules are created.

Name

External URL

Backend Server URL

Pre-authentication

idp1

https://idp1.mydomain.com

https://idp1.mydomain.com

Pass-through

idp2

https://idp2.mydomain.com

https://idp2.mydomain.com

Pass-through

web1

https://web1.mydomain.com

https://web1.mydomain.com

Pass-through

web2

https://web2.mydomain.com

https://web2.mydomain.com

Pass-through

 

No name/URL translation is performed. Servers idp1 and idp2 are SAML 2.0 identity providers, whilst web1 and web2 are SAML 2.0 service providers.

For integration testing with AD FS, we’ll run through the following scenarios:

1.       configuring AD FS as an Identity Provider and simpleSAMLphp as a service provider

2.       configuring simpleSAMLphp as an Identity Provider and AD FS as a service provider

 

Scenario 1 – AD FS Identity Provider (IdP) and simpleSAMLphp Service Provider (SP)

Let’s start with simpleSAMLphp in the SAML 2.0 Service provider (SP) role.

For a basic configuration, there are a number of key simpleSAMLphp files we work with. These are:

          config.php

          authsources.php

          saml20-idp-remote.php

In the authentication sources document (authsources.php), various service provider properties are defined. A single authsources.php containing information of all setups can be used and shared across multiple environments, in our case (web1 and web2), or we may elect to store settings separately, using a unique authsources.php per environment .

For expediency, I highlight the use of a common authsources.php. Each authentication module/configuration is represented by its own section in the document.

Here’s an example of two SAML service provider configurations in a test authsources.php:

 

‘onion1-sp’ => array(

              ‘saml:SP’,

             

              ‘entityID’ => NULL,

‘idp’ => NULL,

              ‘discoURL’ => NULL,

 

              ‘redirect.sign’ => TRUE,

              ‘assertion.encryption’ => TRUE,

              ‘sign.logout’ => TRUE,

              ‘privatekey’ => ‘web1.key’,

              ‘certificate’ => ‘web1.pem’,

                                 

             

 

       ‘attributes’ => array(

      ‘uid’,

       ‘mail’

      ),

       ‘signature.algorithm’ => ‘http://www.w3.org/2001/04/xmldsig-more#rsa-sha256&#8217;,

       ),

 

);

 

‘onion2-sp’ => array(

              ‘saml:SP’,

 

‘entityID’ => NULL,

              ‘idp’ => NULL,

              ‘discoURL’ => NULL,

 

              ‘redirect.sign’ => TRUE,

              ‘assertion.encryption’ => TRUE,

              ‘sign.logout’ => TRUE,

              ‘privatekey’ => ‘web2.key’,

              ‘certificate’ => ‘web2.pem’,

 

 

       ‘attributes’ => array(

      ‘uid’,

       ‘mail’

      ),

       ‘signature.algorithm’ => ‘http://www.w3.org/2001/04/xmldsig-more#rsa-sha256&#8217;,

       ),

 

);

 

Notice the different section names (onion1-sp and onion2-sp) and use of separate certificate keypairs (web1 and web2) in each section.  With the entity ID/identifier set to ‘entityID’ => NULL, simpleSAMLphp will handle the naming for the (RP) identifier of that service provider * and an entity ID is generated based on the metadata URL. In the above config, using web1.mydomain.com and web2.mydomain.com as URLs, this would translate to:

 

https://web1.mydomain.com/www/module.php/saml/sp/metadata.php/onion1-sp

https://web2.mydomain.com/www/module.php/saml/sp/metadata.php/onion2-sp

 

It’s also perfectly acceptable for you to choose your own identifier in the entityID section, rather than defaulting to NULL.

 

The IdP section refers to the entity ID (identifier in AD FS terminology) of the IdP that the service provider (SP) should contact. Like the entity ID value of  NULL used for the simpleSAMLphp service provider, this can also be set to NULL for the idp value. Where multiple identity providers exist, then the user will be shown a list of available IdPs to select from.

 

clip_image012

 

 

 

To corroborate the identity of the service provider, we can (optionally) digitally sign requests and a certificate is required to accomplish this.  Reference to this cert for a service provider (SP) is made in simpleSAMLphp by the privatekey and certificate setting values in the authsources.php.

 

By default, simpleSAMLphp uses the same certificate for token signing and encryption. The certificates comprising the private key (.key) and public key (.pem) will reside in a cert folder  made off the SimpleSAMLphp base configuration path.

 

‘privatekey’ => ‘web1.key’,

              ‘certificate’ => ‘web1.pem’,

 

In this particular configuration, we’ve elected to enable the SP to sign authentication requests (redirect/post), using the the `redirect.sign` =>TRUE option.

While use of signing and encryption is generally considered an unsightly configuration overhead and an optional, use of token signing comes into play with SAML requirements for Single Logout (SLO) and where service providers request specific functionality. As an identity provider, AD FS does expect SAM 2.0 service providers (simpleSAMLphp) to sign logout requests. With this in mind, we elect to use certificates and logout requests are signed by the SP, specifying ‘sign.logout’ => TRUE. 

 

To satisfy the above requirements, when creating the token signing/encryption certificate(s) for simpleSAMLphp, OpenSSL is used here to generate a certificate using the SHA2 signing algorithm. Here’s an example (2 year validity).

openssl req -x509 -nodes -sha256 -days 730 -newkey rsa:2048 -keyout my.key -out my.pem

 

If we’re not satisfied with simply signing tokens, then we can also require the content of the token to be encrypted, by requesting encryption using ‘assertion.encryption’ => TRUE.

 

Our SP is expecting that the AD FS identity provider will provide the attributes uid and mail attributes in the SAML response, as expressed by:

 

‘attributes’ => array(

      ‘uid’,

       ‘mail’

 

 

A SHA2 (SHA256) algorithm is used to sign messages generated by the service provider. 

 

‘signature.algorithm’ => ‘http://www.w3.org/2001/04/xmldsig-more#rsa-sha256&#8217;

 

If you’re not up to date on this and as the help text in the configuration files explain, SHA-1 as a signing algorithm is largely being supplanted by use of stronger schemes.

 

At this point we have the makings of a basic setup authentication-wise. Additionally, simpleSAMLphp needs to be made aware of the AD FS identity provider configuration. This is collected from federation metadata belonging to the AD FS IdP and then stored in the saml20-idp-remote.php file, located in the metadata folder. This file contains configuration details for all remote SAML 2.0 Identity Providers (IdP) known to that service provider.

As we’ll see, the process for pruning metadata and converting it into a simpleSAMLphp friendly format is useable for both service providers and identity providers, thereby applicable for Scenario 2.

Getting the AD FS metadata into a simpleSAMLphp-friendly format is aided by using tools found under the installation page simpleSAMLphp (matching the baseurlpath path). Browsing to the service provider URL, e.g. https://web1.mydomain.com/www shows the simpleSAMLphp installation page.

clip_image014

It’s a good idea to password protect this page. This can be done by editing settings in the config.php file. The settings described therein protect the main admin page and the ensuing metadata pages.

‘auth.adminpassword’          => ‘adminpasswordtobeset’,

‘admin.protectindexpage’      => true,

‘admin.protectmetadata’       => false,

 

In the above, the installation page is protected and metadata left unprotected to allow automated exchange.

The installation pages allow us to perform a number of tests to prepare and configure the installation.

    1. Review the simpleSAMLphp configuration, installed/enabled modules, PHP versions etc.
    2. Use the built-in tools to parse federation metadata from identity or service providers, e.g. AD FS, subject to role, using the XML to simpleSAMLphp metadata converter.
    3. Validate the configuration by testing configured authentication sources (applies to both identity and service provider roles) via the authentication tab
    4. Observe federation metadata endpoints configured and exposed simpleSAMLphp (valid for both identity and service provider configurations)

The Federation tab on the installation page provides useful information relating to metadata and tools for assisting in the setup of federation trusts. At the foot of the federation screen, note the XML to simpleSAMLphp metadata converter.

clip_image016

Use this to convert federation metadata from remote sources into a simpleSAMLphp friendly format.

clip_image018

Here the metadata from the AD FS SAML 2.0 Identity Provider (IdP) needs to be converted for consumption by the simpleSAMLphp service provider. Download the metadata from AD FS and save it to a text file. Metadata is reachable at:

https://<YOUR FEDERATION SERVICE URL/FederationMetadata/2007-06/FederationMetadata.xml

Open the file in Notepad, copy the contents to the Metadata parser in the browser and then click on the Parse button. This will convert metadata into two formats:

(a)    saml20-sp-remote.php used where AD FS is a remote SAML 2.0 Service Provider

(b)   saml20-idp-remote.php used where AD FS is a remote SAML 2.0 Identity Provider

Since AD FS is the identity provider in this scenario, then we require Option (b). In the converted metadata section of the page, find the section relating to saml20-idp-remote.php and copy the text to clipboard. Open the saml20-idp-remote.php file found in the metadata folder of the IdP configuration, paste the contents, appending the parsed metadata into this file and save it.

NB: I’ve read on the simpleSAMLphp forums that it’s also possible to save files to the metadata folder and reference these in your configuration directly. I’ve not tested this, but if interested it’s worth checking out the simpleSAMLphp github on how this can be done.

Back at the installation page, the federation tab is also worth checking out. It shows the SAML 2.0 SP metadata endpoint information needed to configure the simpleSAMLphp relying party on the AD FS side. Here’s an example of a shared configuration file (authsources.php) representing multiple service providers.

clip_image020

If the simpleSAMLphp URL is reachable by the AD FS IdP, then automatic exchange of metadata is possible. Where the metadata page is password protected, then file exchange of metadata can be performed.

Let’s jump to AD FS now. We’ll add the SP instance, utilizing the “default-sp” label as our SAML 2.0  relying party of interest.

clip_image022

Here our endpoint is reachable across the “Internet” so we can automatically configure the RP by consuming the metadata of the service provider concerned. We create our relying party and simply take the URL mentioned above, parse it into the wizard and AD FS consumes the remote XML document automatically. Should this not be possible, say where the metadata document is password protected, or policies at the SP state otherwise, we can import the file using the AD FS wizard as mentioned earlier.

In the Issuance Transform rules on the Relying Party (RP), we can mine the claims from AD (as our claims provider), to populate the simpleSAMLphp requirements. In this example we:

          use the Send LDAP attributes as claims rule to send E-Mail Address and sAMaccountName as uid and mail, required by this relying party

          use a transform rule to send a Name Identifier in the transient format

clip_image024

As can be seen from the above graphic, we’re using E-Mail Address and sAMAccountName to use as incoming claims to populate in our  outgoingSAML assertion as mail and uid respectively.

Incidentally, when initiating federated logon with the SAML 2.0 protocol, a name identifier is typically used.   AD FS as an identity provider, does not send name identifier information in the format expected by simpleSAMLphp. By default, simpleSAMLphp expects a nameid format using the transient identifier (urn:oasis:names:tc:SAML:2.0:nameid-format:transient).

A quick way to get this going, albeit not conforming to SAML specs, is to transform an incoming claim rule, extracted from our AD provider, to populate as an outgoing name identifier.

clip_image026

In the above UI example an incoming UPN claim is transformed into a transient identifier.

Using the claims rule language, the two rules can be expressed as issuance transform rules on the simpleSAMLphp relying party as:

c:[Type == “http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname&#8221;, Issuer == “AD AUTHORITY”]

 => issue(store = “Active Directory”, types = (“mail”, “uid”), query = “;mail,sAMAccountName;{0}”, param = c.Value);

 

c:[Type == “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn”%5D

 => issue(Type = “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier&#8221;, Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType, Properties[“http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format”%5D = “urn:oasis:names:tc:SAML:2.0:nameid-format:transient”);

 

Verifying the RP configuration, we should see both token signing and encryption certificates represented in the appropriate tabs on the relying party, populated among other settings as part of the metadata exchange.

clip_image028

Above, the public key of the token signing certificate, on the Signature tab of the RP.

clip_image030

And on the encryption tab, the public key of the encryption certificate from simpleSAMLphp.

clip_image032

On the Advanced tab, the secure hash algorithm should be set to SHA-256

 

We’re now good to go for testing the configuration within simpleSAMLphp.

Here I select the Test configured authentication sources on the authentication tab.

 

clip_image034

Then choose to test the default-sp configuration.

clip_image036

If the idp value for the service provider in authsources.php is set to NULL, then a drop-down list of identity providers will  be presented (otherwise we’re routed automatically to AD FS)

Here’s an example of a drop-down dialog with the Access Onion identity provider selection.

clip_image038

This particular identity provider is running AD FS 3.0/2012 R2. Connecting from the Internet, we’re routed to the Access Onion AD FS instance (behind the Web Application Proxy) and presented with a logon form.

clip_image040

As part of the logon process the appropriate user credentials are posted to AD FS, in this case user mylo.  Sent back in the SAML response is also the e-mail address of the user, read from the mail attribute in Active Directory, with a value of  nomail@accessonion  for this user.  The resultant SAML assertion can be seen in simpleSAMLphp.

clip_image042

 

Note that the name identifier is not visible on the installation page, although its presence is mandatory.

Click on Logout to check that Single Logout is also functioning and that the two federation partners are configured correctly, signing algorithms are in synch etc.

clip_image044

And we’re logged out, token extinguished/gone.

This is a barebones configuration. Should you wish to employ more expansive configurations, incorporating simpleSAMLphp into the PHP code of your web application (Drupal/Moodle/Joomla etc.), then refer to the simpleSAMLphp website, where there are examples to illustrate this.

Quick note on Name Identifiers

With respect to the earlier comment on the SAML protocol and NameID, when passing a name identifiers of a transient sort, it’s preferable to use an opaque identifier commuted between relying parties that doesn’t reveal the identity of the individual concerned.  To get a better insight into this with respect to AD FS and SAML, I’d suggest reading this MSDN article, as it provides examples on how privacy-bearing claims can be used.

If we wish to use an opaque reference, borrowing from the aforementioned article:

Rule 1: generate a session ID value that can be used as a transient identifier. Add this rule to the claims pipeline.

c1:[Type == “http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname”] && c2: [Type == “http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant”]=> add (store = “_OpaqueIdStore”, types = (“http://sts.mydomain.com/internal/sessionid”), query = “{0};{1};{2};{3};{4}”, param = “useEntropy”, param = c1.Value, param = c1.OriginalIssuer, param = “”, param = c2.Value);

Rule 2:  Using the previously generated session ID, map this to the outgoing claim type  as Name ID using the transient identifier and issue the claim.

c:[Type == ”http://sts.mydomain.com/internal/sessionid”] => issue(Type=”http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier”, Issuer = c.Issuer, OriginalUser = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType, Properties[“http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format”]=”urn:oasis:names:tc:SAML2.0:nameid-format:transient”);

Now let’s look at a sample scenario where AD FS is the SAML 2.0 Servicer Provider (SP) and simpleSAMLphp is the SAML 2.0 Identity Provider (IdP)

Scenario 2 – simpleSAMLphp Identity Provider (IdP) and AD FS Service Provider (SP)

In the identity provider (IdP) capacity, simpleSAMLphp supports a number of authentication methods. These include:

·         Local authentication

·         Single LDAP/AD

·         Multi-LDAP

·         RADIUS

·         SQL

·         OpenID (FB/Twitter etc.)

·         Yubikey

 

That’s quite a diverse set of authentication mechanisms. There are also a number of additional custom modules developed within the community that support even more refined use cases.

We’ll look at a basic setup utilizing local authentication; namely, username/passwords stored in a flat file in the authsources.php file of the simpleSAMLphp IdP. As unglamorous as this might sound, it’s a good starting point for getting a working configuration up and running before mixing it with other more complex setups involving LDAP/RADIUS/SQL etc.

There are a number of files we work with in the identity provider configuration. These are:

          config.php

          authsources.php

          saml20-idp-hosted.php

          saml20-sp-remote.php

On the SAML SP side, AD FS will be using simpleSAMLphp as a claims (identity) provider. We’ll also reuse the simpleSAMLphp SAML 2.0 service provider from Scenario 1 as a relying party (behind AD FS) to illustrate attribute flow.

clip_image046

Here’s the basic logon flow:

1.       User browses to the simpleSAMLphp Relying Party.

2.       User selects the AD FS authentication source and is redirected to AD FS.

3.      Rules logic on the AD FS determines that the user should be directly sent to the simpleSAMLphp claims provider, without showing a realm discovery page.

4.       User is redirected to simpleSAMLphp identity provider for logon where they log on as student

5.       User logs on with local identity (from authsources.php)

6.       User is redirected to AD FS for processing

7.       Claims provider rules are evaluated on the AD FS pipeline

8.       Relying Party rules are evaluated on the AD FS pipeline

9.       User is redirected to the simpleSAMLphp relying party

With all working swimmingly, we’ll end up on the simpleSAMLphp relying party page.

clip_image048

In this logon scenario, we’re using AD FS as Relying Party Security Token Service (RP-STS) in a “headless” capacity. It (AD FS) is not responsible for authentication but must still handle routing of the authentication request to the simpleSAMLphp relying party / test web application.  

In a multiple claims provider scenario, when sending requests via AD FS, we would normally be presented with the Home Realm Discovery (HRD) screen.

clip_image050

As can be seen from the above graphic, with AD FS (via AD) enabled as a claims provider, the “Access Onion” claims provider AND the simpleSAMLphp identity provider are both visible as authentication sources. For this scenario we want to exclusively send logon requests to the simpleSAMLphp identity provider, so the (home) realm selection needs to be suppressed for the simpleSAMLphp relying party/test web application. As mentioned in previous “First Look” posts on AD FS 2012 R2, this can be achieved by declaring the claims provider of choice for the relying party to use for logon in PowerShell.

Set-AdfsRelyingPartyTrust -TargetName “My Relying Party” -ClaimsProviderName @(“SimpleSAMLphp”)

This effectively takes the Access Onion Active Directory out of the mix for logon.

Back to simpleSAMLphp, we begin by enabling the SAML 2.0 identity provider functionality in config\config.php for our identity provider (idp1.mydomain.com) instance.

‘enable.saml20-idp’ => true,

Assigning true to this option enables the SAML 2.0 Identity Provider capability in this instance.

The saml20-idp-hosted.php file in the metadata folder is key for configuring the identity provider. Here’s an example (in bold) calling a local (simpleSAMLphp) authentication method known as example-userpass.

<?php

$metadata[‘__DYNAMIC:1__’] = array(

    ‘host’ => ‘__DEFAULT__’,

    ‘privatekey’ => ‘idp1.key’,

    ‘certificate’ => ‘idp1.pem’,

    ‘auth’ => ‘example-userpass’,

    ‘signature.algorithm’ => ‘http://www.w3.org/2001/04/xmldsig-more#rsa-sha256&#8217;,

    ‘authproc’ => array(1 => array(‘class’ => ‘saml:TransientNameID’,),),

);

You may recognize common aspects of the configuration from the SP scenario applied previously in the authsources.php. Similarly these can be applied to our identity provider configuration in the saml20-idp-hosted.php file.

The identity provider calls the example-userpass authentication scheme from the saml20-idp-hosted.php file.  

The authentication element, expressed as ‘auth’ => ‘example-userpass’, cross-references the appropriate section of the authsources.php file, containing therein a list of users.

‘example-userpass’ => array(

      ‘exampleauth:UserPass’,

      // Give the user an option to save their username for future login attempts

      // And when enabled, what should the default be, to save the username or not

      //’remember.username.enabled’ => FALSE,

      //’remember.username.checked’ => FALSE,

 

      ‘student:pa$$st@dent’ => array(

             ‘uid’ => array(‘student’),

             ‘mail’ => array(‘student@nomail.com’),

             ‘eduPersonAffiliation’ => array(‘member’, ‘student’),

      ),

      ’employee:3mployEEP&ss’ => array(

             ‘uid’ => array(’employee’),

             ‘mail’ => array(’employee@nomail.com’),

             ‘eduPersonAffiliation’ => array(‘member’, ’employee’),

      ),

      ),

 

There are two test users: student and employee, with attributes uid and mail populated. As with Scenario 1, to build a federation trust with AD FS, information must be gathered via exchange of metadata to make the trust possible. For the simpleSAMLphp identity providers, extrapolated metadata from the remote AD FS service provider is stored in the saml20-sp-remote.php file in the metadata folder. On the AD FS side, we need to create a relying party trust for our test web application. We’ll re-use the service provider/relying party created in Scenario 1.

To populate the identity provider with the relevant information, the AD FS metadata file needs to be imported to the simpleSAMLphp identity provider (IdP) instance.

Open the installation page of the identity provider, e.g. https://idp1.mydomain.com/www, authenticating where necessary, and select the federation tab.  

Download the AD FS federation metadata from the metadata endpoint and save it to text file.

https://<YOUR FEDERATION SERVICE URL/FederationMetadata/2007-06/FederationMetadata.xml

Open the AD FS metadata file in Notepad, copy the content to the clipboard and then launch the XML to simpleSAMLphp metadata converter on the federation tab.

clip_image051

Paste the contents to the Metadata parser form in the browser and then click on the Parse button.

clip_image053

Scroll down to the saml20-sp-remote.php section of the web page

clip_image055

Copy this section of text to clipboard.

clip_image057

In the identity provider configuration, open the saml20-sp-remote.php file found in the metadata folder and append the parsed metadata held in clipboard to this file. Save the file.

As a SAML service provider, during passive SSO logons, AD FS makes use of a default name identifier of emailaddress. This can be seen from the metadata screenshot (circled in green):

‘NameIDFormat’ => ‘urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress’,

 

Given that our identity provider prefers the transient format, this can be altered using Powershell by specifying the required NameID format. More on this in a moment….

 

From the identity provider (https://idp1.mydomain.com/www) installation page of simpleSAMLphp, the metadata endpoint information is visible on the federation tab. This corresponds to the Entity ID of the identity provider. This URL is used to configure the claims provider on the AD FS side.

clip_image059

Should the simpleSAMLphp IdP endpoints be visible to support online exchange of metadata with AD FS, then the claims provider can be configured automatically. Where metadata is password protected, or the published path of the endpoint is not reachable (for security reasons), then manual exchange of metadata via file will be necessary.

We now have sufficient information to create the claims provider on the AD FS side. In the Add Claims Provider Trust wizard, the above-mentioned URL is used.

clip_image061

As always I recommend the use of PowerShell over the UI for automating this process. While the initial learning curve/overhead is somewhat higher, it will reduce the margin for human error and also provides documented evidence and a path on how installations/configurations are performed.

Since we are hand-waving authentication to simpleSAMLphp as claims provider, any incoming attributes will need to be processed by AD FS as part of the logon process at both the claims provider and relying party.

Firstly, we’ll override the default AD FS behavior of using SAML 1.1 name identifiers (mail) in favor of the transient identifiers mentioned earlier. To do this the expected name identifier required by the identity provider (simpleSAMLphp) can be stated in PowerShell.

 

Set-AdfsClaimsProviderTrust -TargetName “simpleSAMLphp Identity Provider” -RequiredNameIDFormat “urn:oasis:names:tc:SAML:2.0:nameid-format:transient”

 

The following SAML attributes, expressed as claims rules on the claims provider handler, are defined:

 

1.       Transient Name identifier

c:[Type == “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier&#8221;, Properties[“http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format”%5D == “urn:oasis:names:tc:SAML:2.0:nameid-format:transient”]

 => issue(claim = c);

2.       uid

c:[Type == “uid”]

 => issue(claim = c);

3.       mail

c:[Type == “mail”]

 => issue(claim = c);

 

In a completed configuration, if we were to enable debug and analytics on the AD FS server, we can see the claims processed via Event ID 1000 in the AD FS Debug tracing logs. Note the transient name identifier claim type value of _60b434c232f5cc7048fb85d80ea4c8775d38489f90 being passed when logging on using a test (student) user.

 

ClaimType http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier Value _60b434c232f5cc7048fb85d80ea4c8775d38489f90 ValueType http://www.w3.org/2001/XMLSchema#string Issuer https://idp1.mydomain.com/www/saml2/idp/metadata.php OriginalIssuer https://idp1.mydomain.com/www/saml2/idp/metadata.php Property[http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format] urn:oasis:names:tc:SAML:2.0:nameid-format:transient Property[http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/spnamequalifier] http://sts3a.mydomain.com/adfs/services/trust ClaimType uid Value student ValueType http://www.w3.org/2001/XMLSchema#string Issuer https://idp1.mydomain.com/www/saml2/idp/metadata.php OriginalIssuer https://idp1.mydomain.com/www/saml2/idp/metadata.php Property[http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename] urn:oasis:names:tc:SAML:2.0:attrname-format:basic ClaimType mail Value student@nomail.com ValueType http://www.w3.org/2001/XMLSchema#string Issuer https://idp1.mydomain.com/www/saml2/idp/metadata.php OriginalIssuer https://idp1.mydomain.com/www/saml2/idp/metadata.php Property[http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename] urn:oasis:names:tc:SAML:2.0:attrname-format:basic ClaimType eduPersonAffiliation Value member ValueType http://www.w3.org/2001/XMLSchema#string Issuer https://idp1.mydomain.com/www/saml2/idp/metadata.php OriginalIssuer https://idp1.mydomain.com/www/saml2/idp/metadata.php Property[http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename] urn:oasis:names:tc:SAML:2.0:attrname-format:basic Value student Property[http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename] urn:oasis:names:tc:SAML:2.0:attrname-format:basic 

 

Wonderful J

 

Meanwhile, we need to ensure on the relying party/test web application, our simpleSAMLphp relying party from Scenario 1, that the appropriate rules are applied to ensure that claims originating from the issuer (simpleSAMLphp Identity Provider) are evaluated.

The two test users defined in config.php of the identity provider will emit two SAML attributes of interest for AD FS to process (uid and mail):

‘student:studentpass’ => array(

             ‘uid’ => array(‘student’),

             ‘mail’ => array(‘student@nomail.com’),

             ‘eduPersonAffiliation’ => array(‘member’, ‘student’),

      ),

      ’employee:employeepass’ => array(

             ‘uid’ => array(’employee’),

             ‘mail’ => array(’employee@nomail.com’),

              ‘eduPersonAffiliation’ => array(‘member’, ’employee’),

To reiterate, we wish to pass identity-specific information originating from a SAML 2.0 identity provider (simpleSAMLphp), via AD FS as a SAML 2.0 Service Provider (RP-STS), to our test SAML 2.0 Service Provider/Relying Party (simpleSAMLphp). 

For the relying party, the fact that I’m using simpleSAMLphp (from Scenario 1) is merely for expediency. The application/relying party concerned may well be another application, i.e. a Cloud/SaaS or on-premise offering. However, the attributes mentioned above need to be passed by the identity provider through AD FS to the relying party application. For those not experienced with using claims providers with AD FS, this can sometimes be a little confusing.

In Scenario 1, we created a simpleSAMLphp relying party that surfaced claims from the local Active Directory as the claims provider (identity provider) using the Send LDAP Attributes as Claims claim ruleset.  This particular ruleset is not applicable to claims emitted for our simpleSAMLphp claims provider. Let’s look at the custom claims rule again:

c:[Type == “http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname&#8221;, Issuer == “AD AUTHORITY”]

 => issue(store = “Active Directory”, types = (“mail”, “uid”), query = “;mail,sAMAccountName;{0}”, param = c.Value);

 

Note the reference to AD AUTHORITY. This is specifically targeting the local home Active Directory as the issuer for the claim.  When authentication is handled through the simpleSAMLphp identity provider, this rule is ignored.

Our test application (the same one used in Scenario 1) is expecting attributes uid and mail to be passed from AD FS.  We could add a single rule that states passing all claims rules to be processed by the relying party, covering the claims from the identity provider described above.

c:[]

 => issue(claim = c);

 

This satisfies the requirement of passing the name identifier, uid and mail attributes from the simpleSAMLphp identity provider, but it also passes additional information from the AD FS RP-STS to the relying party.

clip_image063

Note the additional claims such as client IP, forwarded (NAT) client IP, user agent etc.

Alternatively, we could define three pass-through rules, expressly bound to the simpleSAMLphp identity provider through the issuer value.  Instead of sending all claims values, we only emit claims specific to that identity provider for the attributes concerned on the relying party rules.

1.       Name Identifier

c:[Type == “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier&#8221;, Properties[“http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format”%5D == “urn:oasis:names:tc:SAML:2.0:nameid-format:transient”, Issuer == “https://idp1.mydomain.com/www/saml2/idp/metadata.php”%5D => issue(claim = c);

2.       uid

c:[Type == “uid”, Issuer == “https://idp1.mydomain.com/www/saml2/idp/metadata.php”%5D

 => issue(claim = c);

3.       mail

c:[Type == “mail”, Issuer == “https://idp1.mydomain.com/www/saml2/idp/metadata.php”%5D

=> issue(claim = c);

Here we see the difference from the simpleSAMLphp relying party/web application in terms of claims/attributes emitted in the SAML response.

clip_image065

OK.. that’s it for this post. Feel free to post questions and and I’ll get back to you as soon as possible.

As ever: test, play and test a little more Smile

 

 

First Impressions – AD FS and Windows Server 2012 R2 – Part I

In the next few posts, I wanted to take a look at the changes to be found in Windows Server 2012 R2 with respect to Active Directory Federation Services (AD FS).  At TechEd Europe, I was fortunate enough to chat with some of the folks from the Active Directory team about the new enhancements and to cover them here in a little more detail. As you may have read, there are a significant number of changes in the R2 version and I’ll spread coverage of this over a number of posts.

Part 1

          Architecture Changes

          Workplace Join / Bring Your Own Device (BYOD)

o   Windows 8.1

o   iOS Devices

          Web Application Proxy

          Extranet soft account lockout policies

          Lost Device Protection

Part 2

         UI Changes

         Access Scenarios

         Authentication changes

o  Multi-Factor Authentication

o   Context-based Authentication

o   Claims/Non-claims aware applications

o   Policy-based Evaluation

Part 3

          OATH2 support

          Work Folders

          Better event handling / reporting

          Server Core

          Other stuff undiscovered J

Architecture Changes

The use of IIS with AD FS in Windows Server 2012 R2 has been eschewed in favour of a move to kernel-mode (HTTP.SYS). The motive, highlighted in discussions at TechEd, is to improve performance, provide greater sign-in customization options and to assuage concerns for co-locating AD FS and AD DS on the same server (IIS on domain controllers has been a long-standing security no-no).  As the use of federation services goes more mainstream in everyday use with Windows 8.1, this shift is understandable and an important design consideration.  With the new kernel-mode approach, support for running under server core also appears as an option in the new release.

image

From a basic architecture standpoint and overview, the AD FS proxy has been supplanted by a role known as the Web Application Proxy, servicing connections for external clients. The user interface (UI) through the migration to kernel mode is also significantly changed. Authentication undergoes a radical overhaul with a Multi-Factor Authentication (MFA) Adapter available for plugging into Windows Azure Active Authentication and third-party MFA providers. This is also seen in more nuanced behaviour with respect to authentication within the product, reflected in greater flexibility in access control decisions.

With AD FS now built directly built on top of HTTP.SYS, a lot of changes  are abstracted from the user through the new MMC UI and also PowerShell. Nonetheless, it’s worthwhile familiarizing ourselves with kernel mode elements, as they serve a useful role in basic service troubleshooting/configuration . The NETSH HTTP command can be used to query and configure http.sys.

The netsh http show urlacl command can be used to list URL reservations that AD FS makes within http.sys.  Here we can see the /adfs/ path reserved for use.

 

    Reserved URL            : https://+:443/adfs/

        User: NT SERVICEadfssrv

            Listen: Yes

            Delegate: Yes

            SDDL: D:(A;;GA;;;S-1-5-80-2965554544299-213434830-363436364-117610243-975697593) 

 

And there’s this new guy, the Device Enrolment server, whose role becomes more apparent should we wish to make use of new Windows 8.1/iOS client (mobile) integration features.

    Reserved URL            : https://+:443/EnrollmentServer/

        User: NT SERVICEdrs

            Listen: Yes

            Delegate: Yes

            SDDL: D:(A;;GA;;;S-1-5-80-1321940109-3370001082-3650459431-215109509-2472514016)

 

SSL bindings can be reviewed using the netsh http show sslcert command. The AD FS server in this demo setup I’ve created is sts.adfs2.net.

PS C:Windowssystem32> netsh http show sslcert

 

SSL Certificate bindings:

————————-

 

    Hostname:port                : sts.adfs2.net:443

    Certificate Hash             : 1f54c1c62b057dscffgb1aec2b2cbd0876e5c559

    Application ID               : {5d89a20c-beab-4389-9447-324788eb944a}

    Certificate Store Name       : MY

    Verify Client Certificate Revocation : Enabled

    Verify Revocation Using Cached Client Certificate Only : Disabled

    Usage Check                  : Enabled

    Revocation Freshness Time    : 0

    URL Retrieval Timeout        : 0

    Ctl Identifier               : (null)

    Ctl Store Name               : AdfsTrustedDevices

    DS Mapper Usage              : Disabled

    Negotiate Client Certificate : Disabled

 

    Hostname:port                : localhost:443

    Certificate Hash             : 1f52c0d62b0570c6a26c7fec2b2cbd0876e5bc59

    Application ID               : {5d89a20c-beab-4389-9447-324788eb944a}

    Certificate Store Name       : MY

    Verify Client Certificate Revocation : Enabled

    Verify Revocation Using Cached Client Certificate Only : Disabled

    Usage Check                  : Enabled

    Revocation Freshness Time    : 0

    URL Retrieval Timeout        : 0

    Ctl Identifier               : (null)

    Ctl Store Name               : AdfsTrustedDevices

    DS Mapper Usage              : Disabled

    Negotiate Client Certificate : Disabled

 

    Hostname:port                : sts.adfs2.net:49443

    Certificate Hash             : 2f5c41c62b0570c6a26c7fec21d2d0876e5c559

    Application ID               : {5d89a20c-beab-4389-9447-324788eb944a}

    Certificate Store Name       : MY

    Verify Client Certificate Revocation : Enabled

    Verify Revocation Using Cached Client Certificate Only : Disabled

    Usage Check                  : Enabled

    Revocation Freshness Time    : 0

    URL Retrieval Timeout        : 0

    Ctl Identifier               : (null)

    Ctl Store Name               : (null)

    DS Mapper Usage              : Disabled

    Negotiate Client Certificate : Enabled

 

Location-wise, the AD FS application files themselves are no longer held under C:Program FilesActive Directory or C:Program Files (x86). Instead, they’ve moved to C:WindowsADFS. For clarity, this was actually a change instigated first in Windows Server 2012 with the Active Directory Federation Services (AD FS) 2.1 role.  In this folder is the Microsoft.IdentityServer.Servicehost.exe.config file, where, as admins, we’ll be spending more time in the future in order to activate debug functions. From this file all trace options for various services and endpoints can be enabled. In the same folder is a configuration file for the new Device Registration service (DRS), responsible for activation and enrolment of controlled devices and represented by a new (Win8/IOS *) schema class in Active Directory Domain Services (AD DS). The file in question is called   Microsoft.DeviceRegistration.ServiceHost.exe.config. 

Support for the new Device class requires a schema change to Active Directory. For those upgrading an existing Windows setup, the appropriate files can be found on the R2 installation CD under D:SupportADPrep.  From what I’ve seen/tested thus far, to support the new release, you’ll need at least one Windows Server 2012 domain controller, preferably two in any serious deployment scenario. This requirement stems from the use of Group Managed Service Accounts (GMSA) that are generated and maintained by the Key Distribution Service (KDS) on 2012 domain controllers. The new version of AD FS makes use of these GMSA accounts, defined during AD FS installation, that are then shared amongst connecting AD FS hosts. I suggest reading the following backgrounder and bear in mind that the AD FS Windows Server 2012 preview  labs incorporate a workaround for testing purposes, in activating the root key, that is not recommended for production environments.

Update 29/10 –  SamD from the AD product team added that “gMSA is not required to be the service account that ADFS runs on. It is an additional optimization that is available to customers if they have Win2012 domain controllers available.” The traditional service account option is available during installation.

Moving on, let’s take a look at the “broader” access audience that the new version emphasises. This can be immediately seen by viewing the claims descriptions list surfaced on a new AD FS installation.

clip_image002

There are around 40 new claims descriptions available in the AD FS Windows Server 2012 R2 release. As we’ll see, use of these new claims types allow us to make more refined assessments concerning  access to web applications and resources.

Workplace Join / Bring Your Own Device (BYOD)

Through the new Workplace Join feature within R2, AD FS becomes a focal point for mobile access in the enterprise and an integral component in the Microsoft Bring Your Own Device (BYOD) vision. Workplace Join allows hitherto unmanaged/untrusted operating systems such as Windows RT/Windows 8 and IOS to be moved into a more controlled access context, by allowing their registration and affiliation with Active Directory. Devices will register with Active Directory through a Device Registration Service (DRS) and subsequently use an X509 certificate bound to the user context(s) on that machine for device authentication. In a default configuration, users will login via AD FS to initiate the join process using their AD credentials.  To further secure this process, additional factors can be also used with Windows Azure Active Authentication (PhoneFactor) or a third-party authentication provider exposed through the new AD FS MFA SDK.

Devices that are workplace-joined emit additional claims during the logon process. These include:

clip_image004

Certificate support in claims handling has also been enhanced.

clip_image006

Windows 8.1

In order to provide a comparison between old and new with Workplace Join, I began by looking at what claims (and any new ones) are processed from a vanilla Windows 8.1 Pro domain-joined machine, using a simple WS-Federation relying party to validate claims emitted the client and AD FS components.

Firstly via the internal network and the AD FS farm using Internet Explorer. Here the browser uses Integration Windows Authentication/Negotiate and the user silently accesses to the WIF relying party via Kerberos. The usual configuration caveats apply here: the URL of the AD FS and RP instance are in the Local Intranet Zone of IE.

image

To demonstrate a new change, I installed Mozilla Firefox and repeated the logon process. Instead of the Integrated Windows Authentication (IWA)/Negotiate process, the user is presented with a forms sign-in page. This represents a departure from the user experience and behaviour in AD FS 2.0. With the latter,  authentication would be downgraded to NTLM,  because IWA was assumed in the farm configuration and the browser needed to be configured to explicitly support Kerberos for seamless login. Where the latter action was not performed,  the user would receive an NTLM challenge/response prompt, often causing confusion. With the new release, support for IWA is now governed through setting registering User Agent types within AD FS that are capable of supporting Negotiate. Out of the box, this is constrained to IE, meaning any other browser will revert to using forms logon when accessing resources from an internally connected client . Here we see the claims output from a Firefox login:

image

In internal login scenarios (IE/Firefox), we see new claims types emitted concerning location (whether the login request is sourced within the Corporate Network), an Application Identifier (corresponding to the Relying Party Identifier), the Client source IP (or translated) address, an Authentication Method Reference and a Client Request ID.

Then, via an external network through the new Web Application Proxy:

image

In addition to those claims types mentioned earlier is a new claims type for the client forwarded IP (x-ms-forwarded-client-ip) processed at the Web Application Proxy. The insidecorporatenetwork value  is now set to false, as we’re on an outside network.

You may have observed at this point that there are no Device claims. This makes sense if we consider that their use is limited to client types that declare them, i.e. only workplace-joined clients currently make use of the Device class.  

Onto the workplace join process itself. To get your test lab up and running, I recommend reading this TechNet article.

If you follow the lab guide carefully, and, in particular, with emphasis on getting the dependent infrastructure working correctly, then with a little patience and time, you’ll be up and running. I tried this with the basic contoso.com lab setup (a good starting point) and then expanded this in new setup using my own test domain. There are a few gotchas worth pointing out, hoping that you’ll avoid my growing pains …

1.      Don’t use Cryptography Next Generation (CNG) algorithms when configuring your AD Certificate Services. They won’t work.

2.      For simplicity in your CA configuration, I’d opt for use of HTTP Distribution endpoints, particularly if you intend to test “outside” configurations using the Web Application Proxy. Ensure the Certificate Revocation List (CRL) on the Certificate Distribution Point (CDP) and your Authority Information Awareness (AIA) URLs are setup correctly and reachable from the Win 8.1 client. If you’re using Delta CRLs and IIS as the web server for your CDP, don’t forget to allow Double Escaping on IIS in the Request Filtering section.

3.      Ensure the Enterprise CA is trusted by the client and the certificate is installed in the Trusted Root Authorities section of the client. Importing the cert via the AIA endpoint is a good way of testing its availability and installing the certificate. Again, the certificate distribution point (CDP) URLs should be visible to the client.

4.      Issue the AD FS certificate, complete with SAN for the Device Registration Service (DRS), before you begin your AD FS setup. The common name (CN) on the certificate should be the AD FS URL and two Subject Alternate Names (SAN) entries should contain the AD FS URL and one for the Device Registration Service (DRS) provided. For example, I’ve used an example using the MMC snap-in Certificate Request wizard, based on a copy of the default Web Server template for a common name of sts.mydomain.com for the FQDN URL of the AD FS service and also as the first Subject Alternate Name (SAN) entry. A second SAN entry is used for the DRS endpoint, enterpriseregistration.mydomain.com.

 

clip_image010         

5.      As posted on the Technet forums (in the current R2 preview), both the AD FS server and the Windows 8.1 client need to be configured with time-zone of UTC 0:00 or less. My setup is using Pacific Time (UTC -8:00). Don’t ask me, I just blog here J

6.      Don’t forget to enable Device Authentication in Global Primary Authentication settings within the UI or via PowerShell.

7.      Use the Event Log Microsoft|Workplace Join to troubleshoot!! Here’s a collage of  first-hand events to illustrate it’s effectiveness in troubleshooting:

 

clip_image011

URL (enterpriseregistration.xxxx.yyyy) cannot be resolved or reached.

 

clip_image013

Can’t reach the CRL CDP of the AD CS endpoint.

 

clip_image014

Root Authority is not trusted by the client.

 

clip_image015

This message is stating a number of possible issues (generally bad):

 

o   DRS Configuration and Activation was not completed successfully

o   Issues with the SAN on the SSL certificate

o   AD FS Device Authentication has not been enabled

 

Once you start seeing messages like the following, you’re almost there.

 

clip_image016

 

clip_image017

Nice.

 

8.       Take particular note of any errors reported when trying to activate Device Registration Service; namely anything  along the lines of:

WARNING: UPN values that are not included in the SSL certificate have been found in the enterprise. Users with these UPN suffix values will not be able to register their devices. To enable users with the corresponding UPN suffix to register their devices, provide a new SSL certificate containing the values listed below in the subject or subject alternative name.

enterpriseregistration.upn1.contoso.com
enterpriseregistration.upn2.contoso.com

In the case of (8), I’d made the mistake of not registering the appropriate certificates with Subject Alternate Names (SAN) that included the DeviceRegistration CNAME record. Simply re-issuing the AD FS service certificate afterward, setting Manage Private Keys etc. and re-activating DRS in PowerShell was not sufficient to get the configuration working.

The Workplace Join function can be accessed by first accessing the Change PC Settings option on the Windows 8 UI

clip_image019

In PC Settings, choose the Network option

Then select Network followed by the Workplace option:

clip_image021

If your configuration is working, certificates are trusted, appropriate AD FS and PKI endpoints are reachable, stars are in alignment (just joking), then clicking on the Join button leads to AD FS responding with a challenge:

clip_image023

Enter the Active Directory credentials for the user. In this example I’m using, the device is joining a test domain called adfs2.net. Note the AD FS URL (connecting to my R2 instance sts.adfs2.net) at the top of the page. For the auto-discovery of the AD FS Device Registration Endpoints (DRS) a CNAME (Alias) record in DNS needed to be created for the service called enterpriseregistration.adfs2.net. This record points to the host (A) record of the AD FS federation service internally. This allows the discovery process to find the DRS endpoint and in an external setting this would point to the Web Application Proxy,  your own Reverse Proxy or other suitable edge device.

The relying party (RP) for the Device Registration Service is created during the DRS activation process, so there’s nothing additional required on this side.

clip_image024

Connecting Windows 8.1 clients will use the auto-discover function by matching the domain suffix of the user account provided during the join process against the enterprise registration CNAME record for that domain. The join process then attempts a call to the enrollment server web service. Using the adfs2.net domain as an example, the following endpoint is queried:

https://enterpriseregistration.adfs2.net/EnrollmentServer/contract?api-version=1.0

If the service can be reached successfully, the join process is initiated.

clip_image028

The process is now completed and the “join” associated with the Windows 8.1 user profile. I used a Microsoft Live ID account and as can be be seen from the above screenshot, a subsequent AD user called demo with a UPN of demo@adfs2.net,in doing so  providing my AD credentials during the Join. Please note that the Active Directory domain I’m using is also called adfs2.net (dc=adfs2,dc=net) for convenience. In a real-world/production scenario, the DNS domain names used for Active Directory and that of the federation service itself may be different.

The user account is then issued with a self-signed  X509 certificate with an Extended Key Usage (EKU) of Client Authentication. Jumping into the Certificates|User snap-in we see a certificate issued under the user context.

clip_image029

Back to the WIF 3.5 relying party (RP), logging on to the RP from the outside we get redirected to AD FS for logon. Upon successful logon, the following claims are shown.

image

With the Win 8.1 device now connected to the AD domain via a Workplace Join, we see additional claims consummated.

·         IsRegisteredUser

·         OS Version

·         OS Type

·         Identifier (Subject name of the cert)

·         Display Name (corresponding to the Device Name)

·         Registration ID (corresponding to an OU served up in the certificate)

The device itself is registered within Active Directory at the following location: CN=<Device ID>,CN=RegisteredDevices,DC=mydomain,DC=com.

Here’s an example with a SAML 2.0 Service Provider (SimpleSAMLphp), with a Workplace Joined Windows 8.1 client connecting to it.

Inside the corporate network, we see the following:

clip_image033

As tempting it is to delve further into authentication, I’ll refrain from doing so and leave this to a follow-up post. My apologies, otherwise this post will reach biblical proportions in length and we’ll be shaking hands with Santa Claus before we know it.

iOS devices

From testing, the auto-discover function using the enterpriseregistration CNAME record in DNS, described in the previous section, is limited to the workplace join process for Windows 8.1. iOS clients must directly connect to AD FS to initiate the join process. The endpoint settings on the DRS Relying Party refer to a URL of:

https://sts.adfs2.net/Enrollment Server/otaprofile/

This is the DRS Over-the-Air endpoint for non-Windows devices (currently iOS only).

I used an iPad 3 running iOS 6.1.3 for this exercise. If you plan on using self-signed certificates for this type of testing, you’ll need to use the iPhone Configuration Utility to create a profile which can be then used to install the root certificate from your Certificate Services Issuing CA (and any optional chain).

If you’re testing iOS or Windows 8.1 devices in an external setting, it’s worth mentioning that the Web Application Proxy (WAP), which I’ll cover in a moment, doesn’t provide an HTTP Reverse Proxy function. To ensure that any CRL/AIA distribution points are visible in an “outside” testing context, I elected to install IIS on the WAP, publish the CRL/AIA Certificate Distribution Points (CDP) via a UNC from the CA itself to be made available as an HTTP URL on the Web Application Proxy via IIS, making the distribution points reachable from an external perspective. Clearly, this is not something one would do automatically in a production environment, without a bit of forethought, but it works well in a demo environment. You can probably also do this with a kernel mode only approach, but I didn’t have time to test this (yet).

Once the Apple configuration file (.mobileconfig) file had been deployed onto my iPad (via e-mail), a Profile containing the Root certificate was generated and the certificate installed.

clip_image035

clip_image037

With the root certificate or chain correctly installed, going to the AD FS server URL, we should not receive any SSL errors or warnings in the browser, indicating that the chain and CRL/AIA distribution points are reachable. To test this, you can use the IdP initiated sign-on page in the default setup, e.g. https://YOURFQDN/adfs/ls/idpinitiatedsignon.aspx.  From the iPad, here’s the portrait view of the page.

 clip_image039

Playing around, I turned the iPad on its side and we get an automatically resized window. This is a nice feature in the new UI in AD FS 2012 R2 that supports dynamic adjustment and positioning of elements through CSS, resizing pages accordingly across various devices and user agents (think mobile client).

clip_image041

In order to kick off the Workplace Join, we point Safari to the endpoint DRS mentioned earlier:

https://sts.adfs2.net/Enrollment Server/otaprofile/

This redirects the browser to a sign-in page where we need to logon with the AD account that will be bound to the iOS device for the workplace join.

clip_image043

Logging on with the demo@adfs2.net account I used in the Windows 8.1 example, the Safari page remains open in the background and the foreground switches to the install profile option on the mobile device.

image

The install profile option and Workplace Join install option appears:

clip_image047

Clicking on the More Details option, we can see that the AD FS Token Signing Certificate (public key) and the Device Enrollment Encrypted Profile Service are referenced during the profile installation.

clip_image049

Clicking on Install Profile

clip_image051

Once the profile is installed we see a Certificate issued to the device, issued with a common name of MS-Organization-Access, as per the Windows 8.1 join process.

clip_image053

Returning to the profile screen we see the completed Workplace Join profile

 clip_image055

NB: The Demo Auth360 profile is the imported .mobileconfig containing the root certificate from earlier.

Web Application Proxy

Sitting in front of the AD FS farm is a new optional role, similar to the AD FS Proxy in AD FS 2.0, called the Web Application Proxy. This is a completely redesigned component, built to cater for federation services scenarios as well additional access scenarios beyond those seen in AD FS 2.0. 

As with DirectAccess in Windows Server 2012, more roles are being moving into the mainstream product and the Web Application Proxy is a module in the Remote Access role within Windows Server 2012 R2.

clip_image056

Configuration of the proxy itself also moves to the Remote Access Management snap-in.

clip_image057

A configuration wizard is provided to connect the proxy to the back-end AD FS farm and a service account is required to register with the AD FS server(s) during installation. This service needs to be a member of the local administrators group on the AD FS farm.

Once connected to AD FS, a number of simple options are available for configuration.

clip_image059 

The UI is at this stage is admittedly basic, but as with DirectAccess in 2012, there’s a greater emphasis on using wizards to get the job done and whatever can be done in the UI can be done (and more) via PowerShell; a PS configuration script is provided as a summary at the end of each publishing wizard rule to demonstrate this point.

As with TMG/UG we can publish/proxy a particular URL or URIs/paths of that URL expressed as separate publishing rules on the proxy , e.g.

www.mydomain.com/ (as one allow all rule) versus

www.mydomain.com/app1/ as Rule#1

www.mydomain.com/app2/ as Rule#2

www.mydomain.com/app3/ as Rule#3

An interesting under-the-covers capability is support for Server Name Indication (SNI).  SNI, initially provided in Windows Server 2012, allows for multiple certificates to be bound to a single IP listener. Prior to IIS 8.0/SNI, sharing IP addresses amongst multiple websites was limited to the network endpoint and their IP:Port binding. SNI is a TLS extension that provides the hostname of the server the client is connecting to during handshaking. This allows much greater flexibility when configuring the proxy. With the move to kernel-mode, all the hard lifting is done through the UI or via PowerShell. familiarity with NETSH HTTP will also assist in any troubleshooting or ad-hoc configuration. The majority of browsers support SNI, although Windows XP in any configuration using Internet Explorer does not.

The current preview of the proxy in the R2 release provides for connections as:

1.       A reverse web proxy, connecting to back-end servers via HTTPS;

2.       A pre-authentication web proxy, connecting to AD FS via HTTPS to validate credentials

a.       For claims aware web applications

b.      For non-claims aware web applications using Kerberos

When we publish a new AD FS compatible application (pre-authentication), the proxy pulls the RP list/ configuration from the AD FS farm. Polling is done (looking at the event logs) every minute.

Using a Windows Identity Foundation (WIF) test relying party application from another test domain (psid.local),  here’s an example of a publishing rule:

Add-WebApplicationProxyApplication -BackendServerUrl ‘https://rp.psid.local/app9/’ -ExternalCertificateThumbprint ’91D8014979B9CDEF9C907171F7CE9AF398E66DC6′ -ExternalUrl ‘https://rp.psid.local/app9/’ -Name ‘WIF Test Application’ -ExternalPreAuthentication ADFS -ADFSRelyingPartyName ‘WIF 3.5 Application’

This is a pre-authentication rule, meaning that AD FS process the login request, UI surfaced and  validates access and authentication credentials through the proxy via a back-channel connection before access to the relying party is processed.

To complete this round of testing, I wanted to validate Workplace Join from an “outside” network via the proxy. DRS endpoints are automatically published, meaning no specific additional publishing rules needed to be created.

On the Windows 8.1 client, I removed the client from the Join agreement created earlier in order to re-attempt the join via the proxy from the external network. When we attempt a join again from the “outside” via the Web Application Proxy, clicking on Join generates the following page.

clip_image065

The user ID is automatically populated in the form, carried over from the Join request.

Testing from the “outside” now, when we access our WIF application RP from our Workplace Joined client (via the Web Application Proxy), we’re served up with a sign-in form.

clip_image067

That’s expected as we’re now an Extranet client (using MS terminology). This is confirmed by looking at the base AD FS configuration and the primary authentication provider serving up forms login for external clients.

clip_image068

“Extranet” users are automatically assigned to the forms authentication sign-in process, whereas Intranet users are assigned Windows Authentication, browser considerations notwithstanding. For those familiar with fiddling with Local Authentication Types in web.config on the AD FS proxy/farm in AD FS 2.0, making this available through the UI and Powershell is a boon J

Going back to our relying party application, we can see in the produced claims that the client connection is not through the corporate network and is via Web Application Proxy using the following claims:  

http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork

http://schemas.microsoft.com/2012/01/devicecontext/claims/isregistereduser

clip_image070

The client is outside the corporate network and the user is now registered. As a simple test, if we only want to allow Registered Users access to our RP claims web application, we could do this through an Authorization Rule that states that only Registered Users are permitted access:

c:[Type == “http://schemas.microsoft.com/2012/01/devicecontext/claims/isregistereduser&#8221;, Value =~ “^(?i)true$”] => issue(Type = “http://schemas.microsoft.com/authorization/claims/permit&#8221;, Value = “PermitUsersWithClaim”);

Logging on with a non-workplace joined client from outside the corporate network, we are denied access.

 

clip_image072

Error pages are customizable and that’s something we’ll cover in Part 3.

As I touched on earlier, we can use SSL bridging scenarios incorporating wildcard certificates on the front-end (proxy) and named certificates (on the back-end) in publishing scenarios. The pre-authentication parts allows integration with claims and non-claims aware (Kerberos) applications. Applications such as Exchange, which are not claims-aware or non-SAML kerberos claims SharePoint web applications can be configured via the Web Application Proxy. From testing rich client applications such as ActiveSync and Outlook, which use Basic/NTLM application, these are not currently supported on the Web Application Proxy either in a pre-authentication or pass-through capacity. The proxy defaults to SNI and this is not supported by some mail clients.  We’ll cover this and other authentication scenarios in Part 2.

Just to wrap up, here are some observations from testing:

        The proxy can translate host names in URLs but not path names. Make sure that the published path matches that of the application;

         There’s no Edit function in the UI once you’ve created a publishing rule;

         The Web Application Proxy is currently HTTPS only, so no HTTP publishing. Hopefully this will be corrected in the near future as scenarios such as CRL/CDP publishing, which use HTTP are not supported in Reverse Proxy scenarios today. Meanwhile, HTTPS-HTTP bridging, sometimes used in Kerberos Constrained Delegation (KCD) scenarios with TMG/UAG are also not possible as AD FS is HTTPS only.

Extranet Soft Account Lockout

Extranet soft account lockout imposes an option to temporarily lockout “extranet-connected” accounts, via the Web Application Proxy, by not incrementing the AD BadPassword count on the PDC Emulator in AD once the soft lockout threshold is set in AD FS.  If the latter is reached, further logon requests are not passed to AD so that AD Password Policy “hard” lockout measures are not immediately triggered.  As the name suggests, this is a soft lockout option that is governed by use of an observation/sliding window that determines how often in a given period a user may attempt to logon via the proxy before the soft count is reached. The goal here is to frustrate password guessing attempts via brute force/DoS from the outside by nefarious users.

Update 29/10 –  SamD from the AD product team mentioned that the extranet lockout feature was also done with the view that customers with ADDS account lockout policies can prevent DOS attacks on specific user accounts by setting a threshold lower for the ADFS extranet lockout policy. This way the user still has internal access because ADDS has not locked out the user.

Soft Account Lockout can be invoked through the use of PowerShell.

$observationwindow = New-Timespan -Minutes 1

Set-ADFSProperties –ExtranetLockoutThreshold 3 -EnableExtranetLockout $true -ExtranetObservationWindow $observationwindow

Once set, we can see via Get-ADFSProperties, the changes applied:

ExtranetLockoutThreshold              : 3

ExtranetLockoutEnabled                : True

ExtranetObservationWindow             : 00:02:00

 

Here we’ve set the lockout threshold to three attempts with an observation window of two minutes.

From a testing standpoint, In the demo AD Domain setup, “hard” account lockout is not set via GPO.

clip_image074

Attempting to login at the RP WIF test application, we’re redirected to  AD FS for logon. I enter an incorrect password.

clip_image076

The PDC Emulator FSMO role in AD, which monitors the bad password count (badPwdCount) increments by 1, likewise on the second and third bad password attempts.

I entered a bad password five times in successive attempts. Continued attempts to logon with a bad password, once the observation window kicks in fails to increment the count beyond three for the windowed period of  two minutes. Once the window has elapsed, the bad password account is again incremented.

clip_image077

One of the nicer aspects of this setting is that it applies to all endpoints, be they passive or active in nature. This is particularly relevant as it also applies to web services (WS-Trust) endpoints for rich clients, e.g. Office 365.

Lost Device Protection

As covered earlier, devices registered via Workplace Join are registered within Active Directory in the container CN=<Device ID>,CN=RegisteredDevices,DC=mydomain,DC=com. Lost devices can be denied access by disabling or deleting the appropriate object within AD (I moved the device objects to another OU to test this). Access through AD FS is immediately revoked for the workplace joined client.

From testing thus far, devices joined, left and re-registered via Workplace Join are not currently cleaned up within the RegisteredDevices container. Some PowerShell scripting is currently required to enforce this and I would imagine some changes by GA or some scripts made available to manage this process.

Summary

A very long post comes to an end.  Next up, we’ll look at UI changes and authentication/access in greater detail and there’s LOTS to cover. As ever, please feel free to comment, contribute, correct and I’ll get back to you!

Home Realm Discovery– Supporting IWA and Forms Logon Local Authentication Types

A recent use case propped up where it was necessary to support multiple authentication types from a local AD FS instance in an internal access scenario. The mechanics for such a requirement are described in this great post here:

In our case, we’re substituting forms-based logon instead of the X509 client certificates described in the article. I’ve included a third MFA example to illustrate that additional legitimate claims providers can also be incorporated into the code changes.

There are two points of interest to us where an ADFS installation typically displays a user interface. The first is during the initial client logon to the federation server / proxy.  The other is during the home-realm discovery process. Home-Realm Discovery (HRD) is a pre-authentication drop-down box in AD FS that allows users to select their “home” realm, sending them to their identity provider for correct logon processing. In a normal RP-STS scenario, where AD FS is both an authentication provider and a relying party, this could be:

(a)    The default AD claims provider using Integrated Windows Authentication.

(b)   A third-party claims provider / identity provider

Both are valid claims providers in their own right, but I also needed to insert a third forms based “provider” option,  using local AD credentials, into this process. To do this, I used the customization of the HRD code-behind pages discussed in the post above.

First, to ensure that the appropriate realm selection screen is provided each time, we need to disable persistent cookie use for home realm discovery. This is achieved by changing Home Realm persistence in the AD FS web.config. This changes from

<persistIdentityProviderInformation enabled="true" lifetimeInDays="90"/>

to

<persistIdentityProviderInformation enabled="false"/>

Next, we’ll customize the local authentication types within the web.config so that Forms is the default logon method. More on this later…

<localAuthenticationTypes>

      <add name="Forms" page="FormsSignIn.aspx"/>

      <add name="Integrated" page="auth/integrated/"/>

      <add name="TlsClient" page="auth/sslclient/"/>

      <add name="Basic" page="auth/basic/"/>

 </localAuthenticationTypes>

 

When we click on this application, we see the HRD select screen, reflected in the following code in the homerealmdiscovery.aspx.cs code-behind page.

protected void Page_Init( object sender, EventArgs e )

{

 

PassiveIdentityProvidersDropDownList.DataSource = base.ClaimsProviders;

PassiveIdentityProvidersDropDownList.DataBind();

}

As the article mentions, we can add our own logic in the Page Init section of homerealmdiscovery.aspx.cs to customize this approach. The base.ClaimsProviders data source will normally return the list of “enabled” claims providers within ADFS. By modifying the code behind,we define the existing claims providers and our new forms authentication type.  In the following example, we’ve three providers. The provider called AD that will use IWA, an MFA provider that calls out to the third-party IdP  (MFA) and our new custom forms logon provider (Forms).

protected void Page_Init( object sender, EventArgs e )

{

 

PassiveIdentityProvidersDropDownList.Items.Add("AD");

PassiveIdentityProvidersDropDownList.Items.Add("MFA");

PassiveIdentityProvidersDropDownList.Items.Add("Forms");

 

}

 

We then modify the PassiveSignInButton section of the code behind to handle the appropriate authentication and redirection.

 

protected void PassiveSignInButton_Click( object sender, EventArgs e )

    {

   //SelectHomeRealm( PassiveIdentityProvidersDropDownList.SelectedItem.Value );

   switch (PassiveIdentityProvidersDropDownList.SelectedItem.Value)

        {

            case "AD":

                System.Web.HttpCookie cookie = new HttpCookie("MSISPAuthenticationMethod");

                cookie.Value = "AD";

                cookie.Path = "/adfs/ls";

                cookie.Domain = HttpContext.Current.Request.Url.Host;

                Response.Cookies.Add(cookie);

                Response.Redirect("https://&quot; + HttpContext.Current.Request.Url.Host + "/adfs/ls/auth/integrated/" + HttpContext.Current.Request.Url.Query);

                break;

 

            case "MFA":

              System.Web.HttpCookie cookie2 = new HttpCookie("MSISPAuthenticationMethod");

               cookie2.Value = "MFA";

               cookie2.Path = "/adfs/ls";

               cookie2.Domain = HttpContext.Current.Request.Url.Host;

               Response.Cookies.Add(cookie2);

           PassiveIdentityProvidersDropDownList.DataSource = base.ClaimsProviders;

               PassiveIdentityProvidersDropDownList.DataBind();

          SelectHomeRealm( "http://sts.anotherdomain.com/adfs/services/trust&quot; );

               break;

 

            case "Forms":

              System.Web.HttpCookie cookie3 = new HttpCookie("MSISPAuthenticationMethod");

               cookie3.Value = "Forms";

               cookie3.Path = "/adfs/ls";

               cookie3.Domain = HttpContext.Current.Request.Url.Host;

               Response.Cookies.Add(cookie3);

           PassiveIdentityProvidersDropDownList.DataSource = base.ClaimsProviders;

               PassiveIdentityProvidersDropDownList.DataBind();

           SelectHomeRealm( PassiveIdentityProvidersDropDownList.SelectedItem.Value );

            break;

 

   

            default:

                break;

        }

    }

}

In the first case, we invoke the Integrated Windows Authentication (IWA) handler.

In the second and third cases, we restore the original claims provider list,

PassiveIdentityProvidersDropDownList.DataSource = base.ClaimsProviders;

    PassiveIdentityProvidersDropDownList.DataBind();

 

The second case invokes a third-party IDP by calling its home realm identifier. In this example, this is an upstream AD FS IdP recognizable via a http://sts.anotherdomain.com/adfs/services/trust identifer.

In the third and final case – forms logon, we simply select the default claims provider, which you’ll recall, given the order of the web.config has been changed to forms logon. I did this for expediency, as calling formssignin.aspx directly just generated an error.

Each time users connect, they’re now presented with the HRD dialog.

clip_image001[4]

As the folks from http://myitforum.com state in their post, to avoid irritating your users, you can set a cookie expiry period to persist the cookie  for a desired period for a given authentication method. In my test case, this wasn’t valid as users needed to regularly switch between various providers/authentication types. Of course, this has its own disadvantages from a convenience standpoint.

PS: Thanks to a developer buddy of mine, Nico, who continues to exhibit remarkable depths of patience to a  certain .NET neophyte J

Step-up Authentication Scenarios with AD FS 2.0 Part II

With the R2 preview of AD FS in Windows Server 2012 out and the large number of changes that are taking place in the new release, I’m going to be bring this post to a quick end; more an abridged version than was originally intended.

In Part I we looked at weaker authentication schemes for step-up scenarios. In Part II, we move onto two-factor/multi-factor authentication (2FA/MFA) use cases.

There’s no real guided approach for doing this in AD FS 2.0, with solutions invariably becoming customized ones, according to the desired use case.  Whether AD FS is the authentication provider or occupying a hybrid/broker role, the use of authentication contexts, types and URIs provided by the supported SAML and WS-Federation protocols, become triggers for step-up.  Where a context is stipulated, in protocol terms, each is interpreted differently.

SAML supported authentication methods

Authentication Method Authentication Context Class URI
Username/Password urn:oasis:names:tc:SAML:2.0:ac:classes:Password
Password Protected Transport urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
Transport Layer Security (TLS) Client urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient
X.509 Certificate urn:oasis:names:tc:SAML:2.0:ac:classes:X509
Integrated Windows Authentication urn:federation:authentication:windows
Kerberos urn:oasis:names:tc:SAML:2.0:classes:Kerberos

As we saw in the previous post, forcing authentication in SAML logon scenarios provides support for step-up, but at the expense of single sign-on. In passive federation scenarios, if we don’t specify an authentication method in the request, AD FS will apply authentication according to its own supported methods, attempting to match those against the local authentication types section of the web.config on the AD FS node.

AD FS handles the SAML authentication in order of strength, lowest to highest, from top to bottom  as seen in the table: in the default configuration Kerberos is seen as the strongest method. The precedence of the authentication method can be adjusted using the Set-ADFSProperties –AuthenticationContextOrder command to ensure the order meets the requirement we need. The SAML comparison attribute can be used to also influence the authentication method chosen. with AD FS defaulting to a comparison=exact attribute.. As stated in the MSDN article Authentication Handler Overview, if the comparison attribute is set to “better”, “minimum”, or “maximum”, the method of authentication must be stronger than, at least as strong as, or no stronger than one of the specified authentication classes.  This gives us some latitude for using it to invoke the desired authentication method through customization of the sign-in process. With SAML the authentication reference is encoded in the SAML request, and to access and to use the information therein, in order to relay the authentication request to our third-party IdP,  we need to customize our sign-in process  so that the incoming SAML (AuthnContextClassRef) request is decoded. The information we then need needs to be extrapolated so that we can then make the correct routing decision, sending the client to the correct provider. Examples provided on Codeplex hint at how this can be done, by assigning a authentication methods to a relying party using FBA and IWA.

On the other side, let’s look at an example using a WS-Federation based setup.

WS-Federation Passive Profile supported authentication methods

Authentication Method Authentication Context (wauth) URI
Username/Password urn:oasis:tc:SAML:1.0:am:password
Transport Layer Security (TLS) Client urn:ietf:rfc:2246
Integrated Windows Authentication urn:federation:authentication:windows

With the WS-Federation passive requester profile, the authentication type (wauth) parameter is specified in the query string of the browser or can be specified from the relying party application itself. The whr parameter is used to indicate the claims provide to use for logon.

    MFA Step-Up Scenario

    Let’s look at a step-up scenario using WS-Federation with an MFA provider.

image

    In the above graphic, we have a third-party MFA provider handling the authentication requests for internal access.. I’ve not included the AD FS Proxy for external access, but should we wish to do so,  we could adopt our AD FS proxy configuration and:

    – remove the local authentication handlers from the <localAuthenticationTypes> section  of web.config to ensure that MFA is always used in external access scenarios;

    – follow the same methods used for internal authentication described below;

    Internal access step-up scenarios imply the use of the default Integrated Windows Authentication (IWA) handler and the step-up mechanism. With a third-party multi-factor authentication provider, the (MFA) solution is configured within AD FS 2.0 as a claims provider.  I’ll use the example of the WIF-based STS from PointSharp which I mentioned in previous posts.

    In a step-up context, the STS needs to be able to process the required authentication request and pass this back to AD FS and the RP.   With WS-Federation we can do this via the browser as a query string, or, from the web application make use of the wauth and whr parameters to set the authentication method. 

    Step-Up at the Relying Party Application

    Using the WIF 3.5 SDK samples for our relying party, we modify the web.config to specify the desired authentication type.   I’ve chosen the X509 certificate handler. For our WIF application this corresponds to an authentication method value of urn:ietf:rfc:2246

    <federatedAuthentication>
      <wsFederation passiveRedirectEnabled="true" issuer=
    https://sts.mydomain.com/adfs/ls/ realm=https://rp.mydomain.com/ requireHttps="true" authenticationType="urn:ietf:rfc:2246"
      homeRealm=
    https://2sts.mydomain.com/PointsharpSTS <cookieHandler requireSsl="true" />
    </federatedAuthentication>

The homeRealm value is used to specify the claims provider we want to call for step-up, otherwise AD FS itself will attempt to handle the logon, treating as an authentication request for an x509 certificate.

On AD FS we configure the IP-STS as a claims provider.

image

On the IP-STS, we configure AD FS as a relying party

image

For convenience, both the STS and AD FS are sharing the same identity store (AD) and I’ve created a test user called demo in Active Directory and a security group called OTP, whom our user is a member of. We’ll use membership of that group on the PointSharp STS as a means of emitting an authentication method claim that corresponds to the expected authentication type. The claims value, urn:ietf:rfc:2246, is returned when a user logs on using MFA (e.g. OTP+password).

The user demo points their browser to the RP URL and with the web.config modifications, the access request is redirected to AD FS and then to the PointSharp STS as the Windows home realm (whr).

On the PointSharp STS during logon, the back-end PointSharp ID services handles the MFA logon request.  At the initial prompt, the user enters their user ID and AD password:

image

They’re challenged to enter an OTP response (hardware/software token or SMS)

image

Once authenticated, the STS then processes the matching claims rules.

 image

Above, demo is a member of the group OTP, as seen in the claims rule pattern, so a claims type of  http://schemas/microsoft.com/ws/2008/06/identity/claims/authenticationmethod is generated. This is used to match the expected reply of the RP with a value urn:ietf:rfc:2246. and this claims is then passed back to AD FS.

In our test web app we see the appropriate authentication method and values being returned. No claims rules on the claims provider or relying parties (at this point) have been done.

image

Our MFA provider may also support multiple authentication types (AD password, SMS, tokens etc), so the fact that we logon at the STS is not necessarily indicative of a sufficient logon.With  AD FS as the RP-STS, we can also block requests that don’t emit the correct authentication method at the STS on the relying party claims pipeline.

c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", Value =~ "^(?i)http://schemas\.microsoft\.com/ws/2008/06/identity/authenticationmethod/tlsclient$"]
=> issue(Type = "
http://schemas.microsoft.com/authorization/claims/permit", Value = "PermitUsersWithClaim");

 

With the authorization rule in place, another user, demo2, that is not a member of the OTP group, when accessing the RP,  logs on at the PointSharp STS, but gets the following error at AD FS:

image

This translates in the event log to an access denied message:

The Federation Service could  not authorize token issuance for caller ”. The caller is not authorized to request a token for the relying party ‘https://rp……..’. Please see event 501 with the same instance id for caller identity.

 

While we can block in this fashion, it makes more sense to enforce and evaluate a more fine-grained access at the application itself. If the app is intended as an internal-only application though, we can also block access from the AD FS proxy via an access rule.

exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy”]) => issue(Type = “http://schemas.microsoft.com/authorization/claims/deny”, Value = “true”);

Step-Up within the Application

The previous steps described step-up at the web application (relying party), rather than within the application itself. The WIF 3.5/4.0 SDK provides samples for step-up authentication using an example of a low-value and a high-value resource within a given application. Here we’re leveraging step-up against a particular resource within an application.

image

Low-value resources are protected using normal Windows logon credentials (IWA), whereas high-level resources trigger step-up through the use of the certificate handler.

image

This allows us to add in step-up authentication within the application itself, according to the value of the resource.

A note on Virtual Smart Cards

I mentioned in the last post about virtual smart cards (or VSCs).  As an authentication provider, they are available during Windows logon as a credential provider. Given that we wish to expressly enforce step-up at the application, then some sort of adjustment is equired.  It may be possible to suppress the use of the VSC as a credential provider and make it available post-logon for application-only access, something that I’ve not tried, but one could argue that this is a case of the tail wagging the dog. We could also use an alternate account as described in Part I or disable single sign-on in the web.config on the AD FS farm to enforce logon between relying parties. The fact that we’re using IWA for normal logon masks somewhat the behaviour of revisiting the AD FS server when switching between IWA-based relying parties.

As ever, please extensively test before considering doing this sort of thing in a production environment.

Alternatives

What’s been discussed so far relates to solutions that are on the “direct” authentication path from an identity federation standpoint. There are also MFA solutions that involve indirect authentication using multi-factor authentication. When I refer to Indirect MFA, Í mean some other component outside of the federation logon process that handles the strong authentication aspects of logon. Diagrams always help to illustrate the cause Smile…  

      1. Via a non-federation capable proxy or gateway component. This component does not integrate with AD FS, but can provide an MFA capability. All connections to the RP are through the proxy. Post-logon, the proxy does some form of credential delegation to the back-end AD FS service. Here’s an example of a logon scenario with Forefront UAG 2010 on a non-federated trunk. While UAG does support federated trunks (as a relying party), MFA on a federated trunk is not (to my knowledge) possible unless we use an upstream claims provider.

    image

      2.  Via an MFA web agent running on the ADFS proxy as an ISAPI filter or module. This follows the traditional web access management approach of logon via a web agent, with the filter intercepting the call.  The user must logon using the stronger form of authentication before the web application, in this case the AD FS proxy pages are exposed. While functionally “integrated”, the two operate technologically independent of one another.

    image

        3. Via customization of the AD FS sign-in pages, allowing authentication to a MFA provider through web services. Of the three, this is (in my mind) is the most technically plausible, but handling step-up in such cases would also be complex and I’ll refer to that in a moment.

      image

          None of the above mechanisms are particularly well suited to step-up because the MFA logon process wraps around normal AD FS logon process, rather than integrating with it. While they may be valid in other access scenarios, i.e. the logon request is intercepted by a handler that doesn’t understand federated logon.

          Option 3 is interesting as, via a slight modification, it supports illustrating where MFA is going in the next release of AD FS in Windows Server 2012 R2.

          Windows Server 2012 R2

          image

            In AD FS R2, Microsoft are making available an MFA API for vendors to plug-in to and integrate with the federation service directly, allowing for a more rich logon experience. This also extends the concept of using multi-factor authentication not only at a protocol and application level, but at a policy level too, whereby policy per relying party for authentication is achievable. It also suggests that the redirect method via claims providers is being eschewed by Microsoft in favour of a more AD FS centric approach. I suspect the aim here is to provide a more level playing field for integrating external authentication providers with AD FS rather than placing the burden on the vendor and heavy use of customization to support scenarios described..

            What this means for step-up scenarios we shall see. I’ll be looking at this raft of new features with AD FS R2 in future posts.

          Virtual Smart Cards (VSC) and AD FS 2.0

          Before I finish the second article on Step-Up Authentication, I thought I’d write something quick about Virtual Smart Cards (VSC), as they also feature in the next post.

          While Windows 8 has been taking lots of flak for various UI changes, there are a number of nice new features that have snuck in rather quietly. One of these is support for Virtual Smart Cards (VSC). VSC’s  provide an alternate strong authentication mechanism  that removes the need for a physical smart card reader. They emulate the use of a physical card reader via the use of the Trusted Platform Module (TPM) found in most modern  business-grade computers. The TPM module stores the private key of the virtual smart card. While, it’s not two-factor authentication per se, (the virtual smart card is stored on the same device as the crypto module), it is nonetheless an improvement strength-wise over username/password and software-based digital certificates. We’ll give it the official 1.5x times authentication moniker (1.5FA) Smile.

          Private keys are stored in the crypto functionality of the Trusted Platform Module (TPM) of the laptop. The private key is device centric, with the virtual smartcard stored on the same computer. The TPM module needs to be enable on the computer. This can be done manually (woo-hoo!) or via some form of script, or in conjunction with vendor client instrumentation software.

          VSCs provide a number of nice features, but they add a little more added complexity in the setup stakes. Given that we’re emulating physical smart card behaviour, we’re going to need a certificate and that means Certificate Services and an enterprise Public Key Infrastructure (PKI).

          I’ve used a Windows 2008 R2 CA in this example. On the enterprise certification authority (CA)  we can duplicate the built-in Smartcard Logon template found in certificate services using the V2 Windows Server 2003 compatible template.

          image_thumb[25]

          With our new template, entitled Virtual Smart Card, on the Request Handling tab set the certificate purpose to Signature and Smart Card Logon and the minimum key size to 2048. On the Cryptography tab set the cryptographic provider to the Microsoft Base Smart Card Crypto Provider.

          image

          Give (authenticated) users Enrol permissions on the Security tab of the template and then issue the new certificate template.

          image_thumb[27]

          We can use the built-in tool TPM Virtual Smart Card Manager (tpmvscmgr) to provision the smart card.

          tpmvscmgr.exe  create /name Auth360Test /adminkey random /generate

          The generate command formats the TPM virtual smart card so it can be then used to enrol for certificates.

          From a LAN or DirectAccess connected PC we can enrol via use the MMC Certificate Users snap-in, using the Request New Certificate option

          image

          Select the Virtual Smart Card template.

          image_thumb[2]

            During enrolment a PIN needs to be set.

          image_thumb1

          With the VSC enrolled. we can now logout and the virtual smart card should be available for logon.

          Click on our enrolled user and then logon with our PIN.

          image

          I thought I’d give this a whirl with AD FS. For the purposes of this exercise, to support VSC smart logon,  I changed my AD FS proxy configuration to support client certificate authentication, modifying the local authentication types parameter in the web.config on the AD FS proxy. We’ll cover other logon scenarios using VSCs in the next Step-Up authentication post.

          image

          Meanwhile, TLSClient (SSL Client Certificate) is elevated to the top of the list and switched with the default Forms authentication.

          Users accessing the AD FS proxy with a VSC now get a prompt to select their certificate

          image

          Having highlighted and click my user, I now enter the PIN.

          image

          Users not possessing a smart card user certificate will get a 403 error.

          image

          The problem with this approach is that it’s a little generic. We’ve simply configured AD FS to authenticate users based on the presence of an X509 certificate.

          We could always add our VSC users to a security group and reflect this in an authorization claim in AD FS, Even better we could configure authentication mechanism assurance and add an issuance policy to our virtual smart card template and then link that policy to a security group. Microsoft provide a couple of Powershell scripts to allow this, The Object Identifier (OID) of the certificate authenticating at AD FS needs to correspond to the linked claims rule to the OID in our “Virtual Smart Card Authentication” security group. We’ll look at  this in a future post about Bring Your Own Device (BYOD), Workplace Join and Work Folders, new features in Windows 8.1.

          Step-Up Authentication Scenarios with AD FS 2.0 Part I

          This post refers to additional logon schemes that can be supported in AD FS by forcing users to re-authenticate or step-up/step-down authentication to federated web applications. It was prompted by a  recent request from a customer :

          “We wish to connect a SAML 2.0 Service Provider (SP) to AD FS. For security reasons,  we require our internal users to logon (again) when connecting to this web application. All users connecting through the AD FS proxy should be prohibited access.”

          Whether we choose to call this process re-authentication or step-up authentication really depends on the access case.  To meet the requirement, we’ll be breaking single sign-on (SSO) when accessing the web application above by sending parameterised requests from the web application to AD FS, specifying how to handle authentication uniquely for this app.

          Some folks may have pre-conceived ideas about what constitutes step-up, perhaps because it is often associated with multi-factor authentication. While the two do complement one another nicely, step-up is not necessarily multi-factor.  Rather, use of step-up as an access mechanism, is governed by the strength of authentication we wish to accrue to access, at a level commensurate with requirements for protecting that resource. We can use weaker (single factor) authentication where this is deemed sufficient or appropriate.  As an example, a customer may employ two-factor authentication on the outside/edge for all users and then elect to use the AD password, as an additional step-up mechanism for corporate users only to gain access to internal resources.  In authentication strength terms, this is step-down authentication, but in functional terms, it’s designed as a step-up method.

          I make the above point, because in the examples described here, we have users logging onto their workstations either using weak (username/password) or strong (two-factor) authenticating against other federated web applications with these credentials.  In each case, we plan on forcing users to logon again when they access this particular SAML 2.0 web application to “step-up” security.

          This is an internal only access scenario for the enterprise, meaning that users connecting via the AD FS Proxy should be denied access. Since AD FS Rollup 1, we’ve been able to specify Issuance Authorization Rule on the relying party (SAML 2.0 SP) pipeline that allows requests sourced from the AD FS Proxy to be identified and acted on via the claim description: http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy

          Accordingly, we’ll create a deny Issuance Authorization Rule on our SAML web application so that users connecting through the proxy will be blocked.

          exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy”]) => issue(Type = “http://schemas.microsoft.com/authorization/claims/deny”, Value = “true”);

          Sample Scenario

          In a default AD FS farm setup, a domain-joined Windows machine internal user connects to the AD FS farm and authenticates via the Integrated Windows Authentication (IWA) handler using Kerberos/NTLM.  To alter this behaviour, for a given application, and force the user to re-authenticate, we must ignore the existing session cookie.

          With WS-Federation, we can do this at AD FS, via a smart link, by specifying the wauth parameter:

          https://sts.mydomain.com/adfs/ls/?wa=wsignin1.0&wtrealm=https://rp.mydomain.com &wauth=urn:oasis:names:tc:SAML:1.0:am:password

          For a relying party using the WS-Federation Passive Requester Profile (WS-PRP) we can also specify the request in the query string or within application code also via wauth.

          This is a SAML 2.0-based use case though. As a backgrounder, I suggest reading about SAML Authentication Context Classes and Strengths with AD FS. Within the SAML 2.0 protocol, SAML service provider (SP) can emits certain values in the SAML request that ensures that the required authentication method from the SP is honoured by AD FS. From an SAML 2.0 protocol standpoint, this may be accomplished by:

          1. Setting an Authentication Context Class Reference (AuthnContextClassRef) in the requested authentication context from the Service Provider;
          2. Specifying the use of Force Authentication (ForceAuthn) in the request set to a value of true;
          3. Use of a Comparison rule that is set to exact to expressly set the authentication method. Other settings are also possible (which AD FS supports) but are not covered in this post.

          Let’s look at the farm-connected conventions mentioned above in a bit more detail.

          Authentication Context Class Reference

          In Windows SSO logon scenarios, the AD FS integrated handler uses the SAML  AuthnContextClassRef of urn:federation:authentication:windows. On our SAML 2.0 web application, we’ll request a authentication context class reference of urn:oasis:names:tc:SAML:2.0:ac:classes:Password, so that the forms handler (in AD FS) is targeted as the desired authentication handler.

          Force Authentication

          The specification of ForceAuthn=true in the initial SAML request from the service provider specifies that the Identity Provider (IdP) should force re-authentication of the user, even if they possess a valid session with AD FS.

          Comparison Rule

          The SAML 2.0 protocol supports the use of a comparison rule to determine the level of precision to be accorded to the authentication request. If none is specified, AD FS will assume that the attribute is set to exact, meaning that authentication should conform exactly to the AuthnContextClassRef request and is passed to the appropriate handler.

          Configuring Service Providers

          I’ve used two examples here:

          • OpenAM
          • SimpleSAMLphp

          I also planned on including Shibboleth, but hosed my configuration in the process, by reverting the wrong Snapshot of my VM during testing.. *cough*… sorry about that Smile 

          OpenAM

          Using OpenAM as a SAML SP example, we’ll invoke SP-initiated sign-on through the spSSOInit.jsp page.  In the query string we’re specifying the authentication context and the desired force authentication.

          https://myapp.mydomain.com/openam/saml2/jsp/spSSOInit.jspmetaAlias=/acs/sp&realm=acs &ForceAuthn=true&AuthnContextClassRef=urn:oasis:names:tc:SAML:2.0:ac:classes:Password &idpEntityID= http://adfs.mydomain.com/adfs/services/trust&RelayState=https%3A%2F%2Fmyapp.mydomain.com%2Fopenam%2Fconsole

          Note: The above syntax is valid but watch out for white spaces in the example above, not to mention your own domain name.  I’ve added spaces to make the text more legible.

          AD FS will parse the request based on the emboldened items in the query string and ask the user to re-authenticate via forms sign-in.

          SimpleSAMLphp

          In SimpleSAMLphp, we can set the necessary settings in the configuration file authsources.php, specifying the authentication context and force authentication requirement.

          ‘ForceAuthn’ => TRUE,
          ‘AuthnContextClassRef’ => ‘urn:oasis:names:tc:SAML:2.0:ac:classes:Password’,

          Authentication Options

          How we choose to implement our step-up/re-authentication component depends on the question of sufficiency and what is an acceptable method to choose.  For this exercise, this could mean:

          1. re-using the Windows logon identity (re-authenticate);
          2. using an alternate identity from within the same AD forest (step-up);
          3. using an alternate identity residing in a connected forest (step-up);
          4. using an alternate authentication service; a third-party application that provides stronger forms of authentication

          Option 1 – Re-Authentication

          The  simplest option  sees the the user replaying their AD credentials, logging on again via the AD FS form, before gaining access to the web application. This is clearly not step-up and doesn’t afford any significant additional protection, , but may fulfil compliance/auditing requirements for access.

          Advantages Disadvantages
          Simple (uses same identity) Re-authentication not step-up authentication (same password policy)
          Protects against inadvertent access to the application if the user is already logged on (e.g. where user fails to lock OS)

          Security gain is nominal. Requires claims authorization rules on the relying party to differentiate between valid/invalid users.

          Option 2 – Step-Up Same Forest (username/password)

          Option 2 uses another set of credentials held within the same AD FS forest. Access to the SaaS application is limited to those users using these credentials (i.e. their “step-up” identity) and an authorization rule to supplement this.

          image

           

          Advantages Disadvantages
          Authentication is stepped using another identity besides the corporate logon More complex. Requires additional identity to represent users (user management)
          Supports use of stronger password policies on the second identity

          Security gain is moderate.  Same factor (username / password) for step-up identity

            Less user friendly (extra identity)
            Shared authentication sources between identities (no isolation)

          Option 3 – Step-Up Connected Forest (username/password)

          A more complex rendition of this using multiple forests with a single AD FS instance (Option 3):image

          In the above setup we have an account forest for our corporate users and a resource forest, where the AD FS server lives (with the AD FS application pool account running in the account forest). A one way forest trust between the two exists. In this option, the step-up identities reside in the resource forest.

          Advantages Disadvantages
          Authentication is stepped using another identity besides the current logon

          More complex. Requires additional identity / shadow account represented in the  remote forest  (user management)

          Supports use of stronger password policies on the alternate identity

          Security gain is moderate. Same factor (username/ password)  for step-up identity

          Shadow account can use same sAMAccountName in remote forest Less user friendly (extra identity)
          Greater isolation / independence of action from account forest (supports selective authentication) More complex to manage

          For Options 2 and 3, we can also provide further refinement by using AD fine-grained password policies to implement a stronger password policy / account lockout policy applicable to our web application, that exceeds the ordinary password policy levels used for for corporate AD users.

          In all above cases, we should consider further restraining access by passing custom claims on the relying party, to assist in determining whether the user in question should have access.

          From an AD FS standpoint, there are no configuration changes required in the cases described thus far.  You may note, however, that I’ve not yet mentioned IdP-Initiated Sign-On methods. SHAME! Well, there’s a couple of reasons for this, by which I’ll conveniently recuse myself Smile with tongue out 

          1. Firstly, there a nice solution posted on CodePlex, that works similar to the actions described in this post, albeit by customizing the AD FS sign-in pages instead. It allows assigning the use of forms logon logic to relying parties and also covers IdP-Initiated Sign-On and WS-Federation.    Relying parties registered to use the forms logon are registered in AD FS web.config file, thereby bound to the forms handler.
          2. Also, some customers may be unwilling to modify their default AD FS setup because of a fear that it will throw them outside the realms of Microsoft support. However, if you do wish to support IdP-Initiated sign-on scenarios using the methods above (AuthnContextClassRef and ForceAuthn),  then I’m afraid you don’t have much choice as customization of the  code-behind page for  idpinitiatedsignon.aspx.cs is required. Without these changes, sign-on, either via  logintoRP or relaystate  query parameters, will fail as the desired authentication context (AuthnContextClassRef) has not been set and is not passed by the IdP to the service provider. I used the following MSDN article as a reference to customize the  idpinitiatedsignon.aspx.cs and then tested this using logintoRP parameter, with the query string example below.

          https://adfs.mydomain.com/adfs/ls/IdpInitiatedSignon.aspx?logintorp=https:/app.mydomain.com/web1/&RequestedAuthenticationContext=urn:oasis: names:tc:SAML:2.0:ac:classes:Password&ForceAuthentication=true

          In Part II, we’ll look at step-up options with stronger / multi-factor authentication methods (aka Option 4). See ya!

          UAG 2010 and AD FS 2.0 updated articles

          Thanks for those folks who notified me that some of the 2010 articles on the blog have become corrupted. The two original posts have been lovingly restored after applying some TLC.

          November 4th 2010 posting: AD FS – Inside and Outside

          December 3rd 2010 posting: The Triumvirate – UAG 2010SP1, AD FS 2.0 and Kerberos

          Cheers,

          Mylo

          Claims-based access with AD FS 2.0 and PointSharp Identity Federation

          In previous articles we’ve looked at inter-op scenarios with AD FS using gateway solutions such as Juniper SA, Microsoft Forefront UAG 2010 and access management platforms such as OpenAM.  In this post,  we’ll look at using AD FS 2.x with a Windows Identity Federation (WIF)-based Security Token Service (STS) from PointSharp (www.pointsharp.com). This provides us with a broader authentication platform than AD FS from which to make access control decisions.

          In a default configuration, AD FS 2.0 makes use of the local Active Directory as an authentication service. As administrators, we may also wish to further extend authentication options available to AD FS.  A number of mechanisms are available, allowing us to hook into third-party authentication services.

          1. via plug-ins/agents exposed through IIS, either on the AD FS Proxy/Farm to connect to other authentication providers;
          2. customization/ coding sign-in pages to connect directly to authentication providers via web services  or other custom methods;
          3. through a federation trust to another provider, e.g. an IP-STS/IdP. 

          Option 1 is the traditional access management method, using non-federated agents/filters to wrap around IIS. This approach is often independent of AD FS. Option 2 involves customizing the logon process within AD FS, e.g. customizing forms-sign-in pages to hook into back-end web services APIs that the third-party authentication service may provide.  Option 3 is the claims provider route using the federation trust model. PointSharp cater for all three solutions. However, I’ll concentrate on Option 3, using their Security Token service (STS) as a strong/two-factor authentication provider .

          To highlight a working scenario, let’s set out some basic requirements:

          • External users, including corporate users, must connect through the third-party STS using  various authentication types, according to the desired requirements:
            • Two-factor authentication (hardware token, soft token or SMS)
            • An alternate password credential store (non-AD)
            • Credentials from the Corporate directory (e.g. AD)
          • Internal users, connected to the corporate LAN, should be able to connect to relying parties using their Windows logon credentials (Kerberos/NTLM).
          • Applications must support SAML or WS-Federation in an external facing scenario and IWA (Kerberos/NTLM) for internal users.
          • The solution should support claims-based access control to the federated web application according to the desired authentication method

          The PointSharp Identity Federation component (STS) is a .NET / Windows Identity Federation (WIF) application. It services authentication requests by connecting to a core-access management application via web services.

          image

          In logon flow terms, an abridged view of the process is:

          1. The external User connects to Relying Party Web Application
          2. Browser redirect to AD FS Proxy. AD FS local authentication types are disabled. A claims provider  is defined and the authentication request is passed to this.
          3. Browser redirect to PointSharp Identity Federation STS. User logs on. Policy-based access control and claims processing is performed. SAML token is issued.
          4. Browser redirect to AD FS (RP-STS). Perform claims processing on Claims Provider and Relying Party.
          5. Browser redirect to Relying Party for authorization and access to application.

          Users connect to  the PointSharp Identity Federation claims provider (configured) via AD FS, to provide two-factor authentication for external access scenarios.  In order to bypass the (in-built) AD claims provider for AD FS external access, whilst continuing to provide a Windows SSO experience to corporate users, we make a  couple of configuration changes in AD FS proxy and farm nodes:

          • Disable all local authentication types on the AD FS Proxy to pass authentication requests to the PointSharp STS. This is done to bypass home realm discovery (HRD) mechanisms and remove the proxy as an authentication layer. We do this by removing the forms, basic and X509 authentication types within the web.config of the AD FS Proxy in the microsoft.identityServer.web section:

            <localAuthenticationTypes>
            </localAuthenticationTypes>

          • On the local AD FS farm we adjust settings to ensure that the default Active Directory claims provider, not the PointSharp claims provider, is used for authentication of users connecting via the internal/corporate network.  We do so by customizing the homerealmdiscovery.aspx.cs on the AD FS farm to ensure that the AD claims provider is used for Windows logon. Refer to this blog article on how to accomplish this.

          With the above changes, all logon requests via the AD FS proxy will now be handled by the PointSharp STS.

          Before continuing further, let’s look at how the PointSharp Identity Federation component (STS) and the backend PointSharp authentication services work to support desired authentication types.  To accomplish this, we’ll need to dig a little deeper into how identities are stored/used within the configuration.

          Configuration Storage

          As with the majority of Access Management (AM) solutions out there, it’s worthwhile pointing out the distinction between a store used for identity (read-only) lookup purposes, such as a user repository,  versus the store the AM solution uses for holding (writing) configuration options concerning user/profile/preferences. Typically, configuration or data storage is represented in a single aggregate store where information about access identities is written. Conversely, user storage(s), may consist of multiple repositories, which we read user information from.  PointSharp uses an LDAP store, e.g. AD LDS, AD or other LDAP v3 compliant servers for configuration/data storage. The store retains information concerning the users profile, the authentication methods used/supported, additional secrets etc. Sensitive information within the store is encrypted or (optionally) the entire storage container itself.

          User Storage

          In PointSharp lexicon, user storage is used to define an entry point within a repository for basing scoped searches/extractions from. We can then subsequently target items extracted for authentication/authorization processing. User storage may be one or many directories (AD/LDAP) or specific containers (organizational units) within one or many directories.  Optionally, we may then target a desired authentication method against defined user storage types.

          image

          With a given user storage, via scoping options and the use of an LDAP filter , we define objects of “interest” in the storage and, at an attribute level, define various attributes, e.g. logon ID, to be used. This could be a security principal such as  sAMAccountName, userPrincipalName or uid, subject to the object class. In the above screenshot, a User Storage called “inetOrgPerson” has been created,  and within this store (AD),  searches have been limited to include object classes of the inetOrgPerson type from given OUs. The (LDAP) search filter in the chosen user storage is:

          (&({usernameAttribute}={username})(objectClass=inetOrgPerson)(objectCategory=person))

          There’s some latitude here on what we may wish to include/exclude as objects of interest, for logon purposes, abstracted from the logon process normally associated to the native directory. For example, disabled accounts, which might sound bizarre, can also be exposed via user storage. Attributes such as UserAccountControl are available to expose/include in a scoped search within user storage, thereby allowing subsets of users for remote access,  not normally available in a local authentication context to be used. We may wish to make these available purely for external access. In practical terms, imagine that we have a subset of users that we don’t want to be able to interactively logon to AD, from a domain-joined PC, yet should be able to logon externally (only) via our Identity Federation STS. Here’s an example of an LDAP scope that targets disabled users to be defined at a storage level. 

          (&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))

          User storages are processed iteratively. We can include a number of user storage types according to access needs and once we’ve defined them, identify the types of authentication we wish to use directly (via the storage) or indirectly through access policy.

          Authentication Services

          image

          PointSharp, through back-end authentication services, provide authentication types available directly through listeners via web services or RADIUS, according to the access scenario. Since we’re dealing with identity federation here,  this equates to web services. At this point, we can make available a given authentication type to be used in the identity federation process (e.g. SMS) or elect to use a more fine-grained policy-based authentication process. Smart Authentication (SmartAuth) refers to a policy-based / attribute-based access  workflow executed during logon. Through these policies the authentication type to use for a connecting user is determined. This allows for more granular authentication flows to meet requirements. Moreover, this can also be further refined at the (front-end) Identity Federation component (STS) via claims-based access control.

          Using the user storage concepts, let’s have a look at two identity federation scenarios. The first is a “basic” approach using the default Active Directory, available as a user store for moderating external access.

          Basic Scenario (Single Storage)

          image

          In the above setup, we’re “scoping” our storage based around using various OU’s within AD. The first storage uses sAMAccountName for internal users using their Windows logon ID, the second uses userPrincipalName (UPN) for external users. In this example, sAMAccountName is analogous to EmployeeID and userPrincipalName to the emailaddress of the external user. Each respective set of identities live within their own OU’s within Active Directory.

          Complex Scenario (Multiple Storage)

          image

          Similar to the basic setup, we’re also scoping our user storage at OUs within a given store. In this case we’re also adding additional repositories, such as a Partner/Affiliates store (e.g. Extranet), to pull in their identities for usage in logon scenarios ….

          With the user storages defined, we then define individual authentication types within the back-end PointSharp authentication service and expose these as individual listeners, invoked directly by the caller. In our case, this is the PointSharp Identity Federatrion component calling a smart authentication rule. to adopt more fine grained authentication decisions at logon.

          image

          In the above policy, I’ve elected to use membership of a Windows group (in user stores) to target required authentication types.  This involves static management of  a group, so it may be less desirable than using something like a UPN or Email address, matched against a particular suffix to offer a more dynamic evaluation.

          image

          For example, a dynamic evaluation can be used, as in the above example, to attach an authentication method to users with an @auth360.net UPN suffix to use an OATH token. I’ll cover dynamic evaluation using directed authentication types and responses in a later post.

          With PointSharp Identity Federation, we specify the use of a smart authentication rule as the authentication method

          image

          Users logging on from a relying party externally are  redirected to the PointSharp STS. (Note: I’ve already setup the PointSharp STS up as a claims provider within AD FS).

          image

          Within the PointSharp authentication service, if you recall from the earlier MemberOf smart rule graphic, we’ve identified four authentication types: OATH, SMS, PointSharp Password and AD Password. OATH tokens are event or time-based OTP schemes using hardware, software and SMS-based logon mechanisms. Both support (optional) challenge/response password/OTP combinations from the user repositories and the login process adapts to this according to the rules defined with the PointSharp authentication service.  In addition, the PointSharp Password is an alternate login credential that can be called upon and is used in cases where customers do not wish to employ two-factor authentication, nor expose the AD password to external access. Instead, they wish to use a separate password source, independent of AD, with separate password/lockout policies, that can be used to provide claims-based access via the PointSharp STS to their web applications. Should we also we wish to make AD password-access available as a possible authentication type, this is also included in the example. Remote lockout conventions can also be applied to AD users, independent of the AD password policy, to ensure that remote access lockout does not necessarily incur a AD password lockout, and to prevent Denial of Service (DoS) lockout on a given user.

          Within the PointSharp authentication service admin UI, in a storage called AUTH360, four users have been created for testing:

          image

          •  oathman is a user using an OATH token (hardware token / soft token)
          •  smsboy is a user using an SMS authentication method
          •  psidgal is a user using a PointSharp password
          •  adkid is a user using an AD password

          From within PointSharp Identity Federation (STS ) we can define claims-based access rules to be passed onto AD FS. To accomplish this, we create custom claims rules on the STS that conform to the authentication type we desire. This is then injected in the SAML token and consumed as a claim by AD FS, as the RP-STS, for further processing, and passed on to the RP. For example, the four authentication types defined within the SmartAuth rule are now processed at the STS :

          image

          These are passed back via the custom claims definition:

          http://schemas.auth360.net/ws/2008/06/identity/claims/access

          On AD FS, we create a claims description that conforms to the above description

          image

          On the PointSharp Identity Federation claims provider, we pass the above claims as well as any additional claims that we also elect to emit.  On the claims provider pipeline in AD FS, we configure Acceptance Transform rules to pass the Access Type claims and any other rules that the Claims Provider STS has made available:

          image

          On the relying party application we define our issuance transform rules.

          image

          I’m using SimpleSAMLphp, a SAML 2.0 Service Provider, as my Relying Party. AD FS, as a broker, provides the necessary bridging between the WS-Federation passive STS of PointSharp and, in this case our SAML 2.0 RP. In the “groups” claim we pass an inbound custom customs claims definition that transforms the authentication method http://schemas.auth360.net/ws/2008/06/identity/claims/access and emit this as a  SAML attribute that SimpleSAMLphp can then consume:

          c:[Type == http://schemas.auth360.net/ws/2008/06/identity/claims/access] => issue(Type = “groups”, Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType);

          I’ve setup up a basic “Hello World” PHP application, which calls the SimpleSAMLphp libraries and then display the processed attributes in the web page. In our example, the access type (and authentication type) is expressed via the groups SAML assertion in array [0] –LOA4-AD. This is a user logging on who is a member of group LOA4-AD (using AD credentials).

          Array
          (
              [groups] => Array
                  (
                      [0] => LOA4-AD
                      [1] => users
                      [2] => members
                  )
          
              [http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn] => Array
                  (
                      [0] => adkid@auth360.net
                  )
          
          )
          

          At the relying party, we’re now at liberty to make authorization decisions based on the incoming claim, according to the strength of the authentication type. I’m using SimpleSAMLphp here as an example, but the same conventions can be applied to other WIF-based RPs/STS such as SharePoint.

          In a future post,  I’ll look at more refined policy assessments using access based on dynamic evaluation and SAML authentication contexts such as SAML AuthNContextClassRef and WS-Fed AuthenticationMethod in RP/SP initiated-sign-on scenarios. Meanwhile, I hope you enjoyed the post.

          Release Notes for AD FS 2.0 RU3 updated

          Working with a customer recently, we ran into problems with RU3 and the sharing of SAML signing certificates between RPs in their test environment. After applying RU3, as mentioned in the previous post, additional manual actions are required. However, it turns out, following a nice long troubleshooting call with those lovely folks at support, that there are is more to this tale:

          1. The PostReleaseSchemaChanges.ps1 script applies only to AD FS Windows Internal Database (WID) configurations. The script is provided with the RU3 update under the SQL sub-folder.

          2. AD FS SQL database configurations need to run a script locally on a SQL Server node. This file is known as RelaxedRequestSigningCertsv2.sql  and is available via a newly updated article on the support site (KB 2790338) or directly via the following link:

          http://gallery.technet.microsoft.com/scriptcenter/SQL-script-to-relax-unique-5ce353d1

          The updated release notes for RU3 can be found here:

          http://support.microsoft.com/kb/2790338

          Please read, share and alert your fellow AD FS brethren Smile

          AD FS 2.0 – Sharing Signing Certificates across RP Trusts

          AD FS 2.0 Rollup 3 provides support for the sharing of signing certificates between multiple relying parties. Prior to RU3, each relying party trust, should they elect to use one, required a unique signing certificate and attempts to share signing certificates between RPs would generate the following error:

          MSIS7613: The signing certificate of the relying party trust is not unique across all relying party trusts in AD FS 2.0 configuration

          So, following the release of RU3, I was fully expectant to see this fix working.   Following various tests and assistance from PSS, it turns out this is an optional “tweak”, rather than one that is activated automatically through deployment of the rollup, i.e. a script needs to be run to activate this capability.  Following the installation of RU3, in the C:\Program Files\Active Directory Federation Services 2.0\SQL folder is a PostReleaseSchemaChanges.ps1 PowerShell script. This needs to be run on the primary AD FS server from an elevated Powershell prompt.  Once this is done, you should find that you can now configure RP trusts with the same signing certificate.

          To test this I used two SimpleSAMLphp (SSP) service providers (App1 and App2)  with online metadata endpoints.

          https://app1.mydomain.com/module.php/saml/sp/metadata.php/default-sp

          https://app2.mydomain.com/module.php/saml/sp/metadata.php/default-sp

          Both Relying Parties (RP) are using the same X509 certificate key pair as defined in the authsources.php file.  Creation of the two relying parties was then possible and exchange of metadata possible without AD FS throwing an error.

          AD FS 2.0 Rollup 3 (RU3) is out

          As of today 13/02, AD FS 2.0 RU3 is out with a number of updates and hotfixes. This is a cumulative update, so fixes and feature in RU1 and RU2 are contained within.

          Some of the changes included:

          • Fix for SAML 2.0 ActAs for Relying Parties
          • Improved HSM support (performance) for Token Signing and Encryption certificates
          • Changes to  how signature certificate handling and validation of relying parties is handled

          You can apply for the hotfix here:

          http://support.microsoft.com/kb/2790338

          Some of the above have been pain posts for quite a while now , so more on these after testing…

          Exchange 2010 OWA, Claims-based Authentication and AD FS

          I was asked recently whether it was possible to use Outlook Web App with AD FS 2.0 for authentication.  I’d toyed with this in the past with Exchange 2010 SP1, but things had changed in the Exchange mechanics (.NET) since then and this had caused problems for me when using the old configuration with later service packs.  I was curious to see how it would work with Exchange 2010 SP3. Fortunately, it’s always nice to find someone who has dug before you and the following article provided a good guide :

          http://allmsft.blogspot.be/2012/02/owa-sp2-and-adfs.html

          Courtesy of a few adjustments to the author’s notes, which I’ll describe here, it shouldn’t be too long before, it’s possible to have OWA up and running using AD FS and claims on a test rig.

          Let’s assume the initial steps as described in the article have been followed:

          • a new IIS web site has been created
          • OWA virtual directories have been created in Powerscript
          • FedUtil has been run

          We will need to tweak the web.config of the OWA application and you need to watch for case sensitivity issues with the configuration. Equally, the nuances of  FedUtil and how it processes the web.config file can also be a problem. Changes are required in different portions of the file. In the <modules> section of the OWA web.config, the following needs to be add to the header (follow the case exactly):

          <modules runAllManagedModulesForAllRequests=”true”>

          I also found during the FedUtil processing that the above line would often be rejected, with a complaint about System.WebServer tags.  Should you experience the same issue, try setting the remaining configuration changes without setting the module change above, get FedUtil to accept them and then change the web.config once more, in order for FedUtil to reprocess and accept the value.

          Note that you’ll need to add the securityTokenHandlers after the AudienceURI section.

          <securityTokenHandlers>
                  <add type=”Microsoft.IdentityModel.Tokens.Saml11.Saml11SecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″>
                    <samlSecurityTokenRequirement mapToWindows=”true” useWindowsTokenService=”true” />
                  </add>
                </securityTokenHandlers>

          When creating the Relying Party in AD FS and pointing to the metadata path in the browser, you might it failing. In my case, testing the federation metadata would redirect the browser to AD FS, because the published metadata fell under the /owa virtual path and the control of the federation service handler. Creating a virtual directory that pointed directly to the owa\FederationMetadata folder under the web site rectified this.

          You’ll need to specify the /owa path in the browser when accessing the OWA claims website, otherwise you’ll get an error within OWA, something along the lines of:

          An unexpected error occurred and your request couldn’t be handled.


          Copy error details to clipboard

          Show details

          I suspect this is down to the requested URL not matching the Relying Party Identifier.

          Normally when I finish this posts, there’s always a warning about testing…. in this case, this is particularly so. It looks like this is not an extensively tested solution with the Exchange team and that aspects such as Claims to Windows Token Service (C2WTS), while acceptable in the SharePoint world, have not translated to real-world acceptance with the Exchange platform.

          So… TEST, TEST,TEST and Caveat Emptor.

          SAML 2.0 IdP-Initiated Sign-On with RelayState in ADFS 2.0

          Ýet another riveting title Smile Dispensing with WS-Federation, we’ll move onto looking at SAML 2.0 integration with AD FS, in particular IdP-Initiated sign-on. In the last few posts we’ve looked at how AD FS 2.0 admins can manipulate the use of the whr function to assist in the realm discovery process as part of sign-in to AD FS using WS-Federation. With AD FS 2.0 and SAML 2.0, a long-awaited feature has been support for SAML 2.0 RelayState. With Rollup 2, the AD FS team have come up with the goods. Like whr on the WS-Federation side, the use of RelayState allows us to support IdP-Initiated login from a SAML 2.0 identity provider (IdP).

          Before we look at some examples, here’s a few useful tools to aid building and debugging the use of RelayState.

          1. The excellent SAML Tracer plugin for Firefox (https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/)

          2. A relay state generator for AD FS 2.0 to aid us in building the necessary call-back to AD FS. (https://adfsrelaystate.codeplex.com/)

          3. A URL Encoder/Decoder to validate the syntax used for constructing the Relaystate query string. I used this one.. http://meyerweb.com/eric/tools/dencoder/

          To get started, there’s a nice article on the Directory Services blog at Microsoft, as a backgrounder to understanding what’s going on via Rollup 2 and RelayState. http://blogs.technet.com/b/askds/archive/2012/09/27/ad-fs-2-0-relaystate.aspx.

          Let’s have a look at how these scenarios may pan out. Putting my rudimentary skills in Visio 2013 to the test, here are three examples:

          image

          EXAMPLE 1: Remote SAML 2.0 Identity Provider

          In the above example, our user needs to connect, via the Internet, to a remote web application that is configured as a SAML 2.0 Service Provider. This service provider is engaged in a federation trust with AD FS. AD FS as a Relying Party Security Token Service (RP-STS) has the SAML 2.0 Identity Provider (IdP), in the home realm of the user, configured as a claims provider (CP).

          image

          EXAMPLE 2 : Remote SAML 2.0 Identity Provider and Service Provider

          In the above scenario, both the service provider (SP) and the identity provider (IdP) are remote to the organization. This could be a cloud / SaaS application that the RP-STS organization provides access to to both its users and the remote identity provider organization.

          image

          EXAMPLE 3 : Remote SAML 2.0 Service Provider

          In the above example, the Identity Provider (IdP) and AD FS are part of the same organization.  The IdP could be an Access Management platform such as OpenAM, a remote access gateway such as a Juniper SA, or an Extranet ADFS instance with the AD FS RP-STS acting as a broker.

          Access Scenario

          Let’s look at some of the pre-requisites on the AD FS side:

          1. Install AD FS 2.0 Rollup 2 on all instances where AD FS is involved: proxies, farm members and also third-party organizations if AD FS is installed there.

          2. Add the following change to <microsoft.identityServer.web> section of the IIS web.config of all participating AD FS instances, under the /adfs/ls path.

          <microsoft.identityServer.web>
             <useRelayStateForIdpInitiatedSignOn enabled=”true” />
          </microsoft.identityServer.web>

          In this example we’ll evaluate ADFS in a SAML 2.0 Identity Provider (IdP) role within a third party Organization, called Fie, and also as a Relying Party Security Token Service (RP-STS) within the resource organization (Foo).  Fie Users may click on a hyperlink or a bookmark that kicks off the logon process with their IdP, and through the use of RelayState, via the parameterized Relying Party Identifiers provided to the IdP and RP-STS ADFS instances, the user is sent to the service provider application.

          For our web application and SAML 2.0 SP, I’m going to use cloud provider OneLogin. This will act as an application portal. Once logged on via the IdP, the user is sent to the OneLogin portal thru the RP-STS of Foo. Referring to the diagrams above, this access scenario probably best fits Figure 2. Since the web application belongs to Foo, we’re using an indirect trust involving the Foo ADFS instance as an RP-STS. Fie is a claims provider (CP) to the Foo organization ADFS and the web application is a SAML 2.0 Service Provider (SP) that trusts the ADFS instance as an Identity Provider (IdP).

          Here are the service endpoints and relying party identifiers that we need to use to build the appropriate link.

          Using the new notation provided in Rollup 2, two relying party identifiers (RPID) are required in order for the relay to the web application to work correctly. The RPID in ADFS terms is the identifier. For a SAML 2.0 SP, this is the Entity ID of the web application. In some scenarios the entity ID may not be sufficient and additional parameters required. Refer to the Microsoft article mentioned earlier on how this may be further encapsulated into the RelayState. I’ve included the URL encoded and decoded syntax below to give you an idea the syntax we’re forming.

          Here’s the URL Decoded link, broken into three parts:

          1. &RelayState=RPID=http://sts.foo.com/adfs/services/trust
          2. &RelayState=RPID=https://app.onelogin.com/sessions/saml

          Part 1 is the URL of the Identity Provider, Part 2 the query string and RelayState for the RP-STS, and Part 3 state for the SAML 2.0 SP.

          Users logon on at Fie IdP, either through the AD FS proxy using forms-logon, when connecting externally or with their Windows logon ID thru the ADFS farm.  Once we’ve encoded the link, it looks like this:

          https://sts.fie.com/adfs/ls/idpinitiatedsignon.aspx?RelayState=RPID%3Dhttp%3A%2F%2Fsts.foo.com%2Fadfs%2Fservices%2Ftrust%26RelayState%3DRPID%3Dhttps%3A%2F%2Fapp.onelogin.com%2Fsessions%2Fsaml

          And we hit the OneLogin portal:

          image

          I began the post with a smiley, so I’ll end with one.. nice feature Smile..

          AD FS 2.0 Rollup 2 and WHR – We Has Resolution (Part 2)

          In the previous post we covered WS-Federation whr changes in AD FS 2.0 Rollup 2.  With this fix in place and enablewhrpersistence set in our web.config,  let’s look at scenarios on how the configuration can be used to manipulate home realm discovery in greater detail. 

          Our mythical ‘Foo’ organization consists of an existing AD FS 2.0 proxy/farm setup and two claims providers configured:

          1. default AD provider
          2. third-party claims provider providing strong/two-factor authentication (2FA) to Foo users

          Foo has recently engaged in a number of collaboration projects with three other companies: Fee, Fie and Foe. Wishing to further cement these relationships, Foo has elected to setup federation trusts with each of them, and provide access to their local WS-Federation web applications.  The Foo Security Officer, however, has decided that other home realms should not be visible within AD FS in the drop-down box of the home realm discovery page.  All RP-initiated requests via the AD FS proxy must go to their third-party two-factor authentication (2FA) claims provider.  This requirement, however, conflicts with the need to service federated logon for other organizations.

          Given the above constraint, we have a number of options:

          • Use an additional farm;
          • Customize the home-realm discovery pages and logon experience on the existing farm to support the desired user experience for third-parties;
          • Customize the relying party(s) to route the whr request;
          • Use out-of-the-box features.

          Not being much of a code monkey, let’s look at options out-of-the-box. With the new configuration, there are now five claims providers Foo has to deal with.

          1. Active Directory Claims Provider (0)
          2. 2FA Claims Provider (1)
          3. The Fee Organization Claims Provider (2)
          4. The Fie Organization Claims Provider (3)
          5. The Foe Organization Claims Provider (4)

          Foo AD FS Proxy Customization

          For external access, as per security requirements, only the 2FA claims provider should be visible directly from the proxy, making it the default selection for external access. This is arranged  on the AD FS Proxy side by modifying the homerealmdiscovery.aspx.cs file and then removing the claims providers, as eligible entries, from the Page_Init section of the file. We need to process their removal in reverse order, starting with the last claims provider in the list, then the next to last etc., until we have the desired CP . For example, with five claims providers, the following changes are made:

          PassiveIdentityProvidersDropDownList.Items.RemoveAt(4);
          PassiveIdentityProvidersDropDownList.Items.RemoveAt(3);
          PassiveIdentityProvidersDropDownList.Items.RemoveAt(2);
          PassiveIdentityProvidersDropDownList.Items.RemoveAt(0);

          We’re left with claims provider (1) in this example, the 2FA provider. Note the order may vary according to order created.

          Once this has been done, the following line also needs to be added :

          SelectHomeRealm( PassiveIdentityProvidersDropDownList.SelectedItem.Value );

          This will default logon to the 2FA provider claims provider at the AD FS proxy. 

          Foo AD FS Farm Customization

          For users with managed clients/corporate PCs in the Foo organization, we need to ensure that realm discovery is also handled in the right manner. 2FA is not a requirement internally, but SSO via the Windows logon token is desirable. While we covered this in a previous post, it’s worth repeating here. On the AD FS Farm, the Page_Init section of the homerealmdiscovery.aspx.cs file needs to be set so that it defaults realm selection to the Active Directory claims provider.

          SelectHomeRealm ( PassiveIdentityProvidersDropDownList.SelectedItem.Value );

          If this is not set, then all claims providers are visible on the home realm discovery page, something which we don’t want to trouble internal users with on the corporate network. 

          With persistence enabled on the home realm discovery page (of the Proxy), a user may fall foul of cookie handling if he/she works from home, logs on and then returns to work, only to discover that the cookie has persisted and the browser points them to the 2FA provider.  We can temper the cookie behaviour of the AD FS proxy by disabling persistence within the web.config on the AD FS farm.

          <persistIdentityProviderInformation enabled=”false”/>

          Connecting Organizations

          For users from other organizations connecting to Foo; e.g. Fee, Fie and Foe, we rely on smart links from AD FS instances in these organizations to route the request and for the home realm cookie to be written correctly via the whr parameter. Note that these claims providers could also use non-Microsoft identity providers/issuers, such as a Juniper SA (SAML) or a PointSharp WS-Federation Identity Provider, such as . 

          While useful, smartlinks are not without limitations.  Firstly, we’re assuming the relying party is a WS-Federation based web application.  If the relying party is a SAML 2.0 web application then the WS-this approach is not applicable. The solution described here does not work and a different type of customization is required. More on this in a future post. The second limitation concerns users from claims provider realms bookmarking Foo (federated) web applications. Should the home realm cookie expire, accessing a bookmarked RP web application will fail as it routes them to the 2FA provider. While Rollup 2 made persistence via whr possible, we need to workaround this shortcoming. We could set the lifetimeInDays value of the cookie in the homerealmdiscovery.aspx.cs of the Foo Proxy to such a high value that this would not be an issue.  Sadly, this is not entirely foolproof either. Browser configuration for users in partner organizations, e.g. Delete browsing history on exit,  may influence whether the realm cookies are retained or not.  Whatever setting is opted for by the resource organization (Foo) is something that will need to be communicated with partner organizations.

          AD FS 2.0 Rollup 2 and WHR – We Has Resolution!

          Delving further into the dark arts of AD FS 2.0 in this post, we look at whr and home realm discovery, together with smart links,  and how these assist in claims provider trusts with other organizations (particularly in light of changes in Rollup 2).

          Developing a strategy for Home-Realm Discovery (HRD) is an essential part of any AD FS configuration. In scenarios where an organization has multiple claims provider trusts, things tends to get a bit complicated,,,

          ADFS 2.0 Rollup 2 contains a fix relating to use of the whr parameter. The Release Notes explain the issue to date:

          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.

          You may recall that, in previous posts, we looked at ways in customizing the use of realm discovery and claims provider selection via the homerealmdiscovery.aspx.cs page. This was done to suppress claims provider selection to make life easier for our users.  The link talks about such access scenarios.

          https://blog.auth360.net/2012/04/22/ad-fs-2-0-and-multiple-claims-providers/

          In the above scenarios we looked at defaulting the AD FS Proxy to another provider (a strong authentication provider) and removing realm selection options by the use of the Select Home Realm parameter. In the back-end we set the default claims provider to be AD, thereby sending all authentication requests to Active Directory. This conveniently avoided home realm discovery by hard-coding the selection of the claims providers to the strong authentication claims provider on the AD FS Proxy and the built-in AD provider on the back end.

          When add additional claims providers to the mix, e.g. federation capable partner organizations, we hit the issue described in the release notes, because suppression of the home realm selection and the whr limitation means that remote users are sent to the strong authentication provider. 

          To the rescue, the release notes explain:

          The Update Rollup 2 for AD FS 2.0 update resolves this issue by not overwriting data in the home realm cookie when home realm information is provided through the whr parameter. To set a home realm cookie that contains the whr parameter when the home realm cookie is not present, set the following configuration in the Web.config file:

          <persistIdentityProviderInformation enabled=”true” lifetimeInDays=”30″ enablewhrPersistence=”true”/>

          When the setting is configured, AD FS 2.0 will create a home realm cookie with the identity provider that is specified in the whr parameter when the whr request is sent, and when there is no home realm cookie. The whr request does not overwrite the cookie when there is already an existing home realm cookie.

          In other words, AD FS 2.0 creates a home realm cookie for the identity provider/issuer specified, if one doesn’t already exist and persists that cookie according to the lifetime specified in the values set in web.config

          For remote access scenarios with partner organizations and trusted claims providers, this provides a nice way to govern access through the use of IdP-Initiated smart links. For the resource partner organization, we continue to allow our logon pages being served up for our users, whilst allowing us to keep a strong authentication logon for our AD FS proxy and default AD provider in the back-end. Additionally, the practical benefits of this fix are more apparent in IdP-Initiated sign-on scenarios, when there are  multiple web applications in the resource organization that need to be surfaced.

          For example, we have a portal application in Organization A. The application provides an IdP Initiated smart link on its web page to an Intranet SharePoint 2010 application located at Organization B. To complicate matters, other applications are exposed through nested links in the Intranet web application, linking to other claims-aware applications such as SharePoint Teamsites and Organization B wants to make these applications available also to Organization A.

          From an access point-of-view, prior to Rollup 2, this became very messy very quickly.  A User in Organization A logs on to the SharePoint Intranet web application via  an IdP-initated smart link and later in their session try to access the Teamsites web application. The local (resource) AD FS instance will serve up the home realm discovery page and the claims provider drop-down, because the whr parameter does not persist the home realm cookie.  If we’ve also suppressed the claims provider in the selection page (on the proxy), by customizing the homerealmdiscovery.aspx.cs, we have a double whammy as the user can no longer access their home realm .. OOPS!

          As of Rollup 2, this behaviour is contained because the home realm selection via the whr in the IdP-initated smart link now stores the home realm cookie.

          Let’s walk through a use case:

          image

          A user in Organization A (e.g:bar.com) clicks on a smart link on their portal (https://portal.bar.com) to access an claims-aware SharePoint Intranet web application in Organization B. This link  calls the AD FS instance in Organization B (e.g:foo.com) with the whr parameter set to the ADFS instance of Org A (http://sts.bar.com/adfs/services/trust) and the wtrealm parameter set to the Intranet web application (https://intranet.foo.com).

          Here’s the smart link in Organization A:

          https://sts.foo.com/adfs/ls/?wa=wsignin1.0&wtrealm=https://intranet.foo.com&whr=http://sts.bar.com/adfs/services/trust

          When clicking on the link, the user is redirected by the Organization B AD FS instance to Organization A, where the user authenticates against their local Active Directory with their Windows token or logon via the AD FS proxy sign-in page (if they’re on the Internet). Following successful authentication, the client is sent back to the Organization B STS, claims are processed, before being redirected to the relying party (SharePoint) for further evaluation. Assuming our claims are set correctly, the user gains access to the SharePoint Intranet web application and because we are running Rollup 2 with the change in web.config,  a home realm cookie based on the whr reference is stored.

          Now let’s imagine that our user, surfing around on the Organization B Intranet web site,   clicks on a link on the Intranet web application which calls another onsite relying party , Teamsites. The Teamsites web application is located at the (example) URL of  https://teams.foo.com. This is a different relying party and so the access and claims  of the federated identity again need to be validated. Because the home realm cookie this time has been written correctly (through successful logon via the Intranet application), a relying party (RP-initiated) sign-on is now possible and the user can, assuming they are authorized, gain access to the Teamsites web application successfully without being scuppered by home realm discovery.

          Prior to Rollup 2, the user would have been faced with the Home Realm Discovery selection screen, or, if we’d suppressed the claims provider, to the wrong home realm.

          image

          With the enablewhrPersistence=”true” value set in web.config, courtesy of Rollup 2, the  home realm discovery page is now bypassed because the home realm details are stored in the cookie stored during the successful IdP-initated sign-on and RP-initiated sign-on now works.

          YAY!!

          ADFS – SAML 2.0 Identity Provider and SaaS Service Providers

          Under ADFS 2.0, Microsoft support the SAML 2.0 IdP Lite and SP Lite modes described in the Liberty Alliance/Kanatara Initiative interop program and eGov Profile 1.5, covering the essentials for identity federation.  From a configuration perspective, we often come across issues in the federation setup phase that can trip up ADFS and the administrator. Sometimes this is the case when dealing with SaaS applications, where there may be minimal customization possible from the vendor standpoint, with the application living in a multi-tenant environment. Tweaking “their side” may not be possible or something that the vendor is comfortable or capable of doing.

          In this post, we’ll look at some of the integration issues one may experience when integrating ADFS as an IdP with SAML 2.0 SP web applications using the SAML 2.0 POST profile. There are a number of useful debugging aids/tools that can assist in the troubleshooting process.

          All of the above are useful to lean on and gather problem-solving information during troubleshooting.

          Scenarios covered here are using ADFS 2.0 as an Identity Provider (IdP).

          ADFS Configuration

          There are some common gotchas when configuring the relying party in ADFS in the UI.

          Issuer / Identifier

          Based on the SAML specs, the <samlp:AuthnRequest> must include a <saml:Issuer> including the EntityID of the Service Provider. If you’re creating the relying party manually, double check that the relying party identifier you specify matches that of the EntityID specified in the XML file provided by the Service Provider.

          <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
          <EntityDescriptor entityID=https://sp.yourdomain.com/yourapp xmlns="urn:oasis:names:tc:SAML:2.0:metadata">

          If there’s a mismatch then this may trigger an error:

          Exception details:
          Microsoft.IdentityServer.Service.Policy.PolicyServer.Engine.ScopeNotFoundPolicyRequestException: MSIS3020: The relying party trust with identifier ‘
          https://sp.mydomain.com/foo’ could not be located.

          In the above example, the expected identifier is https://sp.yourdomain.com/yourapp was mis-configured in the UI by yours truly with an identifier of https://sp.mydomain.com/foo .. back into the UI to correct…

          image

          Certificates

          Certificates deserve an entirely separate post, but not today Smile…… a few caveats though.. for token signing, the requirement for signing of SAML sign-in requests by the RP is optional. Should you wish to enforce this it is configurable via Powershell … besides importing the requisite token signing certificates and handling the lifecycle management of your certificates in a diligent fashion, bear in mind that if you also want to employ encryption (and possess an encryption certificate) ADFS will sign assertions by default. Moreover, it will use AES-256 for encryption. This can cause issues with service providers that support weaker algorithms. If you experience this issue, then you may be forced to disable claims encryption for that relying party. This can be accomplished through Powershell (set-ADFSRelyingPartyTrust). I’ve not found a way to tweak this in a more refined fashion than on/off…

          Another problem to be wary of is certificate revocation checking… if a Certifcate  Distribution Point (CDP) is referenced in the signing or encryption certificate of one of the federation partners, then the corresponding party must be able to reach that CDP in order to determine the validity of the certificate. This can be problematic, for example, if your security policy blocks connections from servers to the Internet or if the counterpart does not publish it over the Internet. 

          Secure Hash Algorithm

          A common problem when connecting to relying parties, ADFS defaults to the more secure but less well known hash algorithm of SHA-256. SHA-1 is more widely used with the majority of  cryptographic libraries. If you’re getting an error such as this:

          SAML request is not signed with expected signature algorithm. SAML request is signed with signature algorithm http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 . Expected signature algorithm is http://www.w3.org/2000/09/xmldsig#rsa-sha1

          Flip the secure hash algorithm over to SHA-1 on the Advanced tab in the Relying Party trust to fix this.

          SAML Integration

          Contained within are some SAML integration issues experienced that I wanted to share.

          NameIDPolicy Format URIs

          Normally contained with an authentication request is the NameID Policy and format attribute(s). There are numerous ways in which intended or unintended settings can trip up the federation process. When troubleshooting, start with the ADFS event logs as these can be quite revealing.

          Here are a couple of sample problem cases.

          EXAMPLE 1

          PROBLEM: A federation trust has been setup between Organization A and SaaS Provider B. Users attempt to access their SaaS application via SP-initiated logon. After logging on an at ADFS, the SAML redirect returns them to the web application where it fails with a generic HTTP 500 error at the web application.

          The SAML authentication request had a NameID Policy that could not be satisfied.
          Requestor:
          https://sp.yourdomain.com:443/yourapp
          Name identifier format: urn:oasis:names:tc:SAML:2.0:nameid-format:transient
          SPNameQualifier: 
          Exception details: 
          MSIS1000: The SAML request contained a NameIDPolicy that was not satisfied by the issued token. Requested NameIDPolicy: AllowCreate: True Format: urn:oasis:names:tc:SAML:2.0:nameid-format:transient SPNameQualifier: . Actual NameID properties: Format: urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified, NameQualifier:  SPNameQualifier: , SPProvidedId: .

          Looking at the ADFS logs we find MSIS1000 errors. As the above message indicates, the requester is expecting a format of Transient, but we’re sending a format of Unspecified.  Oops…

          SOLUTION: The Event Log message also reported that “Use the AD FS 2.0 Management snap-in to configure the configuration that emits the required name identifier.” In other words, fix the identifier… our mismatched name identifier in this case can be fixed by creating a transform Rule and setting the NameID format to what the relying party expects -  transient. In the example below, we take the incoming claim of Common Name and pass it to the Name Identifier in Transient form.

          c:[Type == "http://schemas.xmlsoap.org/claims/CommonName"]
          => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"] = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient");

          Note that the use of transient and persistent formats in identifiers are intended to provide privacy-preserving pseudonyms to protect the identity of the subject. Persistent assumes that the identifier assigned to the identity remains the same each time the user logs on, whereas Transient properties are per session. If you want to create opaque identifiers during logon, I suggest reading the following useful article:

          http://blogs.msdn.com/b/card/archive/2010/02/17/name-identifiers-in-saml-assertions.aspx

          In my case, the application I was using involved personalization and rendered this approach unsuitable. Also, by transforming Common Name into Transient on the claims pipeline, we are also circumventing the privacy-preserving methods that Persistent/Transient were intended for, as the name is no longer obfuscated. Token encryption can be used to overcome this, but that brings its own caveats.

          EXAMPLE 2

          PROBLEM: A federation trust has been setup between Organization A and SaaS Provider B. Users are attempting to access the SaaS application via an SP-initiated logon process. After logging on an at ADFS, the SAML redirect sends them to the web application where it fails with a generic HTTP 500 error at the web application.

          The SAML authentication request had a NameID Policy that could not be satisfied.
          Requestor:
          https://sp.yourdomain.com/yourapp
          Name identifier format: urn:oasis:names:tc:SAML:2.0:nameid-format:transient
          SPNameQualifier:
          https://sp.yourdomain.com/yourapp
          Exception details:
          MSIS1000: The SAML request contained a NameIDPolicy that was not satisfied by the issued token. Requested NameIDPolicy: AllowCreate: True Format: urn:oasis:names:tc:SAML:2.0:nameid-format:transient SPNameQualifier:
          https://sp.yourdomain.com/yourapp. Actual NameID properties: Format: urn:oasis:names:tc:SAML:2.0:nameid-format:transient, NameQualifier:  SPNameQualifier: , SPProvidedId: .

          Looking at the ADFS logs we see MSIS1000 errors. In this scenario, ADFS is not providing an expected NameQualifier and SPNameQualifier to the Service Provider in the SAML Response.

          SOLUTION:

          Via a claims rule we can insert the relevant information that the service provider is seeking to satisfy the authentication request.

          c:[Type == "http://schemas.xmlsoap.org/claims/CommonName"] => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
          Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType, Properties["
          http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"]
          = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", Properties["
          http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/namequalifier"] = "http://sts.mydomain.com/adfs/services/trust",
          Properties["
          http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/spnamequalifier"] = "https://sp.mydomain.com/webapp");

          Authentication Context

          Authentication contexts allow the service provider (SP) to augment in the assertion, the type  and strength of authentication desired. To increase the chance of (successful) interoperability the <samlp:AuthnRequest> should not include a <samlp:RequestedAuthnContext> element. This recommendation bears out in testing with ADFS. The support for different authentication context classes vary and the semantics often interpreted differently. When processing a SAML authentication request, the interpretation of the relative strengths of the different authentication context classes is up to the responder and AD FS 2.0, by default, interprets the relative strength of these different authentication context classes in its own order. By default, this is:

          urn:oasis:names:tc:SAML:2.0:ac:classes:Password
          urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
          urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient
          urn:oasis:names:tc:SAML:2.0:ac:classes:X509
          urn:federation:authentication:windows
          urn:oasis:names:tc:SAML:2.0:ac:classes:Kerberos

          When the service provider is requesting this information, you may find that out-of-the-box it doesn’t work… let’s have a look at some examples …

          EXAMPLE 1

          PROBLEM : A federation trust has been setup between Organization A and SaaS Provider B. Users are able to logon to the SaaS application via the ADFS Proxy from home or remotely using form-based logon. When they logon internally,  via the ADFS farm, the same users are not able to do so and get an HTTP error. 

          <samlp:RequestedAuthnContext xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Comparison="minimum"><saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef></samlp:RequestedAuthnContext>
          </samlp:AuthnRequest>

          In the above SAML authentication request, the Service Provider (SP) is specifying that the expected authentication context  from ADFS is  urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport. Users doing an integrated windows logon are not emitting this authentication context and instead they transmit urn:federation:authentication:windows in the authentication context to the RP and it may trigger an exception.

          SOLUTION: 

          There are a couple of ways to tackle this problem:

          (a) the service provider may be able to submit the additional authentication context for Windows authentication (urn:federation:authentication:windows) to their configuration.  
          (b) if the service provider does not support this change, we can provide the appropriate value in the relying party response by checking for the presence of NameID and then parsing urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport in the response. For example:
           
          exists([Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"]) => issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", Value = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport");

          EXAMPLE 2

          PROBLEM: A federation trust has been setup between Organization A and SaaS Provider B. Domain-joined users expecting single sign-on through ADFS are being presented with the forms logon handler when accessing the SaaS application internally. They then have to manually enter their credentials per session.

          <samlp:NameIDPolicy  xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" AllowCreate="true"></samlp:NameIDPolicy>
          <samlp:RequestedAuthnContext xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Comparison="exact"><saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef></samlp:RequestedAuthnContext> </samlp:AuthnRequest>

          The service provider was, by specifying a comparison of "exact", forcing the authentication context for all users to be set to PasswordProtectedTransport, inadvertently telling ADFS to downgrade authentication for domain-joined clients to forms logon, thus defeating/breaking SSO for internal clients.

          SOLUTION: Ensure that the SP sets the RequestedAuthnContext comparison to minimum.

           

          That’s it for the moment…… I’ll add to this when new scenarios crop up or via  input from other contributors..

          Automated Update of Federation Metadata with Office 365

          Another Powershell script from the ADFS team that makes life a little easier.

          http://gallery.technet.microsoft.com/scriptcenter/Office-365-Federation-27410bdc#content

          When the token signing certificate of your home AD FS organization expires, then federation metadata between AD FS and Office 365 falls out of synch. Equally, when changes are made on the Office 365 that require updating the metadata, a similar issue arises. The  script provide by the AD FS team checks the that federation metadata is validated regularly and any changes replicated between the two federating parties.

          image 

          What does the script do? It calls the Update-MSOLFederatedDomain cmdlet and updates the settings in both the Active Directory Federation Services 2.0 server and Office 365. It also adds an item on the task scheduler queue:

          image

          It’s worth bearing in mind that the password policy that is being applied to your organization (Enterprise or Standard O365) will render the script unusable in the event of a password change on either the O365 side with the account you specify and the Domain side with the user account used to initiate the scheduled task. It is possible to create service accounts to do this on both sides. However, I’d consider the security consequences of such a change before automatically doing so. This can be done on the O365 side with an Office 365 standard account via the Set-MSOLUser cmdlet. For example,

          Set-MSOLUser –identity user@mydomain.com –PasswordNeverExpires $true –StrongPasswordRequired $true

          The account could also technically be a federated account, but I don’t believe that’s a good idea. In the event that the trust is broken, then a federated account won’t be able to connect to MSOL to update the federated domain information Smile 

          On the AD side, a more suitable compromise may be found by using a least privilege account for the task service account.

          TMG 2010 and Office 365 Single Sign Out with AD FS 2.0

          A while back (June 2011), I wrote a post on how to implement TMG, Single Sign-On (SSO) and strong authentication with Office 365. It was, as it turns out, an incomplete story. 

          Tristan Watkins has written an excellent article on how to implement single sign-out using TMG with Office 365 and ADFS 2.0. It goes into great detail about issues with sign-out from non-federated proxies with ADFS/O365 and explains the various nuances associated with Office 365 sign-in…. you can read this article here:

          http://tristanwatkins.com/index.php/office-365-single-sign-out-isa-tmg-adfs-proxy/