Windows Azure Pack with ADFS and Windows Azure Multi-Factor Authentication – Part 2

ADFS Series

In the previous part of this blog series we installed Windows Azure Pack and Active Directory Federation Services. In this blog we will configure the WAP Admin Portal and the WAP Tenant Portal to use ADFS for authentication. The configuration steps for both sites are very similar with some exceptions. The following steps will be performed.

  • Change the WAP site bindings in IIS
  • Update the WAP database with the new IIS bindings
  • Configure the WAP database to use ADFS
  • Create a relying party in ADFS
  • Create claim rules in ADFS
  • Enable JWT for relying party in ADFS

After completing these steps, every user that successfully authenticates to ADFS can access the WAP tenant site. To prevent a random user from accessing the WAP admin site, an additional step must be performed to enable access for admins.

  • Configure authenticated users for the admin site

Windows Azure Pack accepts User Principal Name (UPN) claims and Group claims. A tenant requires a UPN claim to logon to Windows Azure Pack. When a tenant subscribes to a plan the UPN is made owner of the subscription. A UPN is required as owner for a subscription. The Group claim is optional and can be used to specify Co-Admins for an existing subscription. A common design is to designate an owner of the subscription that is responsible (for example a department head) and add a group claim as co-admins for the subscription (for example a group containing all the departments users). A couple of tests with group claims pointed out that Domain Local Groups will not work (even if you manage to pass them as claims with some custom claim rules) and that Windows Azure Pack will not accept a space in the Group when configuring Co-Admins for a subscription.

<img src=”/images/2014-02-26/01-CoAdmins-req.png” width=600”>

Two components of ADFS are important in relation to Windows Azure Pack. The Claims Provider and the Relying Party. A Claims Provider authenticates a user, create the claims for that user and configures the claims into security tokens that the relying party uses to make authorization decisions. A Relying Party consumes claims in a particular transaction. Claims that originate from a claims provider can be presented and consumed by the relying party. A default installation of ADFS configures a Claims Provider trust to Active Directory. This default Claims Provider trust has a predefined set of Claims, which contains the UPN claim, but does not contain the Group claim.

It is possible to add additional claims at the Claims Provider level or at the Relying party level. If you add additional claims at the Claims Provider level, these claims are available to all relying parties and can also be used for authorization and transformation in a relying party configuration. If you add additional claims at the Relying Party level, these claims will only be available to that particular Relying Party.

This blog will describe the steps for configuring the Tenant Site and the Admin site for authentication with ADFS. You can choose to configure only one site for ADFS and use the default authentication mechanism for the other or use ADFS authentication for both sites. We will first configure the Tenant Site for authentication with ADFS.

Tenant Site

The Tenant Site in Windows Azure Pack provides a GUI where a tenant can perform actions on the available services within the subscriptions the tenant has access to. Windows Azure Pack provides an Authentication Site with an ASP.NET Membership provider for the Tenant Site. In a previous blog I described the steps to configure the Tenant Site for the default Tenant Authentication Site. To configure the Tenant Site for authentication with ADFS perform the following steps.

Change the WAP site bindings in IIS

Out of the box Windows Azure Pack creates the Tenant Site on port 30081 with the internal FQDN of the server running the Tenant Site. For an enterprise organization the Tenant Site will probably be accessible internally and maybe externally, for a service provider it is more likely the other way around. Either way, it is common practice to change the default Tenant Site URL from something like https://NL-IIS-WAP1T3.domain.local:30081 to https://manage.hyper-v.nu. Open IIS Manager on the server that is running the Tenant Site. Right-click the MgmtSvc-TenantSite and select Edit Bindings. Select the existing binding and click on Edit. Change the port from 30081 to 443 and change the self signed certificate to the certificate we created and imported as described in the Prerequisites entry in the previous part of this blog series.

<img src=”/images/2014-02-26/02-Tenant-Site-Bindings.png” width=500”>

If you are running two or more websites on the same server and you want to use the same port (443) and certificate bindings for these websites, you can leverage Server Name Indication (SNI) to enable this. Since you will use different FQDN for the same port and certificate, a wildcard or subject alternate names (SAN) certificate containing the FQDNs is required.

Update the WAP database with the new IIS bindings

The Windows Azure Pack database also contains the URLs of all the endpoints. We need to update the FQDN and Port number of the Tenant Site in the WAP database. These steps can be performed on a server that has the Windows Azure Pack: PowerShell API component installed. In an express installation this components is automatically installed. In a distributed installation this component can be installed with the Web Platform Installer. It is recommended to use the PowerShell ISE (Integrated Scripting Environment), because it will give you Intellisense, but you can also run the cmdlets in a default PowerShell console. Import the MgmtSvcConfig module by running the following command.

Import-Module -Name MgmtSvcConfig

Change the FQDN and port number of the Tenant Site with the following command. Change the FQDN to your own value and the Server entry to the name of your SQL server hosting the Windows Azure Pack databases.

Set-MgmtSvcFqdn -Namespace "TenantSite" -FullyQualifiedDomainName "manage.hyper-v.nu" -Port 443 -Server "SQL01"

<img src=”/images/2014-02-26/03-Tenant-Site-FQDN.png” width=720”>

Configure the WAP database to use ADFS

Logon to a server that is part of the Windows Azure Pack deployment and that is running the Windows Azure Pack: PowerShell API component. This server needs to be able to access the ADFS Federation Metadata endpoint, to update the Tenant Site.

The federation metadata can be queried by appending the following relative path to the ADFS FQDN.

/FederationMetadata/2007-06/FederationMetadata.xml

In this example ADFS is configured on https://sts.hyper-v.nu. Open a browser from the server and connect to the ADFS federation metadata endpoint.

https://sts.hyper-v.nu/FederationMetadata/2007-06/FederationMetadata.xml

Depending on your browser security settings you should be prompted to download and XML file or see its content.

<img src=”/images/2014-02-26/04-ADFS-FederationMetadata.png” width=720”>

Run the following command on the server to create a variable containing the information about your SQL Server hosting the Windows Azure Pack databases.

$ConnectionString = 'Data Source=SQL01;Initial Catalog=Microsoft.MgmtSvc.Config;User ID=sa;Password=P@ssw0rd1'

The following command updates the information in the Tenant Site and references the variable $ConnectionString we just created. The parameter -DisableCertificateValidation is optional and only necessary if you are using untrusted (self-signed) certificates. Execute this command in the same PowerShell session used for creating the $ConnectionString variable.

Set-MgmtSvcRelyingPartySettings -Target Tenant -MetadataEndpoint 'https://sts.hyper-v.nu/FederationMetadata/2007-06/FederationMetadata.xml' -ConnectionString $ConnectionString –DisableCertificateValidation

<img src=”/images/2014-02-26/05-Target-Tenant.png” width=720”>

You can check if the redirection works by hitting the URL https://manage.hyper-v.nu. You should be redirected to ADFS. ADFS will display an error because it has not been configured with a relying party for the Windows Azure Pack Tenant Site.

<img src=”/images/2014-02-26/06-ADFS-error.png” width=720”>

Create a relying party in ADFS

Logon to the server running Active Directory Federation Services. We need to specify the Windows Azure Pack Tenant Site federation metadata when creating the relying party.

The federation metadata can be queried by appending the following relative path to the WAP Tenant Site.

/FederationMetadata/2007-06/FederationMetadata.xml

In this example WAP Tenant Site is configured on https://manage.hyper-v.nu. Open a browser from the ADFS server and connect to the WAP Tenant Site federation metadata endpoint.

https://manage.hyper-v.nu/FederationMetadata/2007-06/FederationMetadata.xml

Depending on your browser security settings you should be prompted to download and XML file or see its content.

<img src=”/images/2014-02-26/07-XML-File.png” width=720”>

Open the ADFS management console. Open Trust Relationships, right-click the Relying Party Trust and select Add Relying Party Trust. This will start a wizard. In the select data source screen of the wizard choose to import data about the relying party published online or on a local network and specify the WAP Tenant Site federation metadata endpoint.

https://manage.hyper-v.nu/FederationMetadata/2007-06/FederationMetadata.xml

<img src=”/images/2014-02-26/08-Add-Relying-Party.png” width=720”>

In the specify display name screen of the wizard enter a name that will easily identify the relying party for administrative purposes. By default the FQDN of the Tenant Site will be populated. Accept the default values on the remaining tabs of the wizard. In the last tab the checkmark allows you to open Edit Claim Rules dialog that we will need for the next step.

Create claim rules in ADFS

The Edit Claim Rules Dialog was opened after completing the wizard in the last step. It can also be accessed by right clicking the relying party trust we just created and selecting Edit Claim Rules. We will start with the User Principal Name. In the Issuance Transform Rules click Add Rule. In the Choose Rule type tab of the wizard select Pass Through or Filter an Incoming Claim as the Claim Rule Template. In the Configure Claim Rule screen specify a descriptive name (in this example Pass Through UPN) and select UPN for the Incoming Claim Type.

<img src=”/images/2014-02-26/09-Add-Transform.png” width=720”>

By default the Group claim is not provided by the Claim Provider. As specified in the beginning in this blog there are two possibilities for adding the group claim. The first option is to add the group claim in the Relying party. This can be achieved by selecting Send LDAP Attributes as Claims, select Active Directory as the Attribute Store and map the Token-Groups – Qualified by Domain Name to the Group Claim. But for this blog we will use the second option and configure the Group claim in the Claim Provider. Right-click the Claim Provider trust that was created out of the box and select Edit Claim Rules. In the Acceptance Transform Rules select Add Rule. Select send LDAP Attributes as Claims. In the next screen, select Active Directory as the Attribute Store and map the Token-Groups – Qualified by Domain Name to the Group Claim.

<img src=”/images/2014-02-26/10-LDAP-Group.png” width=720”>

Next we will need to configure the Relying party to pass through the group claim to Windows Azure Pack. Right-click the Relying party trust that we created for Windows Azure Pack earlier and select Edit Claim Rules. In the Issuance Transform Rules click Add Rule. In the Choose Rule type tab of the wizard select Pass Through or Filter an Incoming Claim as the Claim Rule Template. In the Configure Claim Rule screen specify a descriptive name (in this example Pass Through Group) and select Group for the Incoming Claim Type.

<img src=”/images/2014-02-26/11-Passthrough-Group.png” width=720”>

You can create more advanced scenarios by using Issuance Authorization Rules. For example it is possible to specify that a certain group claim permits access and otherwise access is denied. Enabling a scenario where access to Windows Azure Pack for all users that are member of that Active Directory group is permitted, while all other users are denied access, despite the fact that they are able to authenticate against ADFS successfully.

Enable JWT for relying party in ADFS

With Windows Azure Pack you can use an STS that meets the following requirements

  • Support WS-Federation
  • Exposes a Federation Metadata endpoint
  • Capable of generating JWT tokens with at least ‘UPN’ and optionally ‘Groups’ Claims

JSON Web Token is not enabled by default on the Relying party in ADFS, so we need to enable it. Logon to the server running ADFS and run the following PowerShell cmdlet. Change the name value to the name of your Relying Party trust.

Get-AdfsRelyingPartyTrust -name manage.hyper-v.nu | ft name, identifier, EnableJWT

The EnableJWT value is set to False. To enable JWT we need to change this value to True by running the following cmdlet. If you changed the default TargetIdentifier you should specify the updated value. Verify with the previous cmdlet.

Set-AdfsRelyingPartyTrust -TargetIdentifier 'http://azureservices/TenantSite' -EnableJWT $true

<img src=”/images/2014-02-26/12-Enable-JWT.png” width=720”>

You should now be able to logon to the Windows Azure Pack Tenant Site with ADFS successfully. The configuration for The Admin Site is the same for most parts. I will describe the complete process again so you can configure the Admin Site and the Tenant Site separately by just following the steps.

Admin Site

The Admin Site in Windows Azure Pack provides a GUI where administrative tasks can be performed. You can configure resource providers, manage users and plans. Windows Azure Pack provides an Authentication Site for the Admin site that used Windows Authentication. In a previous blog I described the steps to configure the Admin Site for the default Admin Authentication Site. It is also possible to configure the Admin Site to use ADFS, which allows for more advanced scenarios.

Change the WAP site bindings in IIS

Out of the box Windows Azure Pack creates the admin site on port 30091 with the internal FQDN of the server running the Admin Site. It is recommended to make the Admin Site accessible internal only. But even for an admin it is easier to remember a friendly name and port. For example you can change the default Admin Site URL from something like https://NL-IIS-WAP1A5.domain.local:30091 to https://admin.hyper-v.nu. Open IIS Manager on the server that is running the Admin Site. Right-click the MgmtSvc-AdminSite and select Edit Bindings. Select the existing binding and click on Edit.

<img src=”/images/2014-02-26/13-Site-Bindings.png” width=500”>

Change the port from 30091 to 443 and change the self signed certificate to the certificate we created and imported as described in the Prerequisites entry in the previous part of this blog series.

Update the WAP database with the new IIS bindings

The Windows Azure Pack database also contains the URLs of all the endpoints. We need to update the FQDN and Port number of the Admin Site in the WAP database. These steps can be performed on a server that has the Windows Azure Pack: PowerShell API component installed. In an express installation this components is automatically installed. In a distributed installation this component can be installed with the Web Platform Installer. It is recommended to use the PowerShell ISE (Integrated Scripting Environment), because it will give you Intellisense, but you can also run the cmdlets in a default PowerShell console. Import the MgmtSvcConfig module by running the following command.

Import-Module -Name MgmtSvcConfig

Change the FQDN and port number of the Admin Site with the following command. Change the FQDN to your own value and the Server entry to the name of your SQL server hosting the Windows Azure Pack databases.

Set-MgmtSvcFqdn -Namespace "AdminSite" -FullyQualifiedDomainName "admin.hyper-v.nu" -Port 443 -Server "SQL01"

Configure the WAP database to use ADFS

Logon to a server that is part of the Windows Azure Pack deployment and that is running the Windows Azure Pack: PowerShell API component. This server needs to be able to access the ADFS Federation Metadata endpoint, to update the Admin Site.

The federation metadata can be queried by appending the following relative path to the ADFS FQDN.

/FederationMetadata/2007-06/FederationMetadata.xml

In this example ADFS is configured on https://sts.hyper-v.nu. Open a browser from the server and connect to the ADFS federation metadata endpoint.

https://sts.hyper-v.nu/FederationMetadata/2007-06/FederationMetadata.xml

Depending on your browser security settings you should be prompted to download and XML file or see its content.

Run the following command on the server to create a variable containing the information about your SQL Server hosting the Windows Azure Pack databases.

$ConnectionString = 'Data Source=SQL01;Initial Catalog=MgmtSvc.PortalConfigStore;User ID=sa;Password=P@ssw0rd1'

The following command updates the information in the Admin Site and references the variable $ConnectionString we just created. The parameter -DisableCertificateValidation is optional and only necessary if you are using untrusted (self-signed) certificates. Execute this command in the same PowerShell session used for creating the $ConnectionString variable.

Set-MgmtSvcRelyingPartySettings -Target Admin -MetadataEndpoint 'https://sts.hyper-v.nu/FederationMetadata/2007-06/FederationMetadata.xml' -ConnectionString $ConnectionString –DisableCertificateValidation

<img src=”/images/2014-02-26/14-Target-Admin.png” width=720”>

You can check if the redirection works by hitting the URL https://admin.hyper-v.nu. You should be redirected to ADFS. ADFS will display an error because it has not been configured with a relying party for the Windows Azure Pack Admin Site.

Create a relying party in ADFS

Logon to the server running Active Directory Federation Services. We need to specify the Windows Azure Pack Admin Site federation metadata when creating the relying party.

The federation metadata can be queried by appending the following relative path to the WAP Admin Site.

/FederationMetadata/2007-06/FederationMetadata.xml

In this example WAP Admin Site is configured on https://admin.hyper-v.nu. Open a browser from the ADFS server and connect to the WAP Admin Site federation metadata endpoint.

https://admin.hyper-v.nu/FederationMetadata/2007-06/FederationMetadata.xml

Depending on your browser security settings you should be prompted to download and XML file or see its content.

<img src=”/images/2014-02-26/15-FedMetadata.png” width=720”>

Open the ADFS management console. Open Trust Relationships, right-click the Relying Party Trust and select Add Relying Part Trust. This will start a wizard. In the select data source screen of the wizard choose to import data about the relying party published online or on a local network and specify the WAP Admin Site federation metadata endpoint.

https://admin.hyper-v.nu/FederationMetadata/2007-06/FederationMetadata.xml

In the specify display name screen of the wizard enter a name that will easily identify the relying party for administrative purposes. By default the FQDN of the Admin Site will be populated.

<img src=”/images/2014-02-26/16-Relying-Party-Display-name.png” width=720”>

Accept the defaults values on the remaining tabs of the wizard. In the last tab the checkmark allows you to open Edit Claim Rules dialog that we will need for the next step.

Create claim rules in ADFS

The Edit Claim Rules Dialog was opened after completing the wizard in the last step. We will start with the User Principal Name. In the Issuance Transform Rules click Add Rule. In the Choose Rule type tab of the wizard select Pass Through or Filter an Incoming Claim as the Claim Rule Template. In the Configure Claim Rule screen specify a descriptive name (in this example Pass Through UPN) and select UPN for the Incoming Claim Type.

The Group claim is not provided by the Claim Provider by default. We will follow the same procedure to add the Group claim as we did with the Tenant Site. If you already added the Group claims to the Claim Provider for the Tenant Site configuration you can skip this. Right-click the Claim Provider trust that was created out of the box and select Edit Claim Rules. In the Acceptance Transform Rules select Add Rule. Select send LDAP Attributes as Claims. In the next screen, select Active Directory as the Attribute Store and map the Token-Groups – Qualified by Domain Name to the Group Claim.

Next we will need to configure the Relying party to pass through the group claim to Windows Azure Pack. Right-click the Relying party trust that we created for Windows Azure Pack Admin Site earlier and select Edit Claim Rules. In the Issuance Transform Rules click Add Rule. In the Choose Rule type tab of the wizard select Pass Through or Filter an Incoming Claim as the Claim Rule Template. In the Configure Claim Rule screen specify a descriptive name (in this example Pass Through Group) and select Group for the Incoming Claim Type.

<img src=”/images/2014-02-26/17-Claim-Rules.png” width=500”>

Enable JWT for relying party in ADFS

JSON Web Token is not enabled by default on the Relying party in ADFS, so we need to enable it. Logon to the server running ADFS and run the following PowerShell cmdlet. Change the name value to the name of your Relying Party trust.

Get-AdfsRelyingPartyTrust -name admin.hyper-v.nu | ft name, identifier, EnableJWT

The EnableJWT value is set to False. To enable JWT we need to change this value to True by running the following cmdlet. If you changed the default TargetIdentifier you should specify the updated value. Verify with the previous cmdlet.

Set-AdfsRelyingPartyTrust -TargetIdentifier 'http://azureservices/AdminSite' -EnableJWT $true

<img src=”/images/2014-02-26/18-Enable-JWT.png” width=720”>

In contrary to the Tenant Site you are not yet able to logon to the Windows Azure Pack Admin Site with ADFS.

<img src=”/images/2014-02-26/19-Access-denied.png” width=720”>

The admin site requires one additional step for allowing access through ADFS.

Configure authenticated users for the admin site

By default no user has access to the Windows Azure Pack Admin Site using ADFS. We can specify access for users or groups. Run the following command on a server, that is part of the Windows Azure Pack deployment and that is running the Windows Azure Pack: PowerShell API component, to create a variable containing the information about your SQL Server hosting the Windows Azure Pack databases.

$ConnectionString = 'Data Source=SQL01;Initial Catalog=Microsoft.MgmtSvc.Store;User ID=sa;Password=P@ssw0rd1'

To verify the current users and groups that have access to the Windows Azure Pack admin site run the following command.

Get-MgmtSvcAdminUser -ConnectionString $Connectionstring

<img src=”/images/2014-02-26/20-Get-MgmtSvcAdminUser.png” width=720”>

The cmdlet to add a user or a group is the same

Add-MgmtSvcAdminUser –Principal DOMAIN\<username or groupname> -ConnectionString $ConnectionString

For this example we will create a Global Security group in Active Directory containing the user accounts that require access to the Windows Azure Pack admin site.

<img src=”/images/2014-02-26/21-Group.png” width=500”>

Add the group by running the cmdlet and verify if the group is present.

<img src=”/images/2014-02-26/22-Add-MgmtSvcAdminUser.png” width=720”>

If you are not able to access the admin site after configuring access for a group you probably have a mismatch with the value specified in the cmdlet and the actual Group claim that is issued by ADFS. The sharp observer will see that the in the screenshot that the domain name is not similar to the rest of the values in the blog.

In this blog we are using hyper-v.nu as the DNS domain name and hypervnu as the NetBIOS domain name. The two claim types we used in this blog will both reference the DNS domain name.

  • Token-Groups – Qualified by Long Domain Name > The claim will be in the format DnsDomainName\Groupname (hyper-v.nu\group)
  • Token-Groups – Qualified by Domain Name > The claim will be in the format FirstDnsDomainName\Groupname (hyper-v\group)

Neither claim type will result in a format with the NetBIOS domain name. If your desired group claim is referencing the NetBIOS domain name you could create a transform rule that changes the DNS Domain Name in the NetBIOS domain name.

I know from personal experience that it can be very useful to know what values are issued by ADFS. In the next part of this series we will look at some possible ways to look at the content of the claims that are passed from ADFS to Windows Azure Pack. This will give some more insight into what is going on behind the scenes and help you to specify the correct values for Co-Admins on subscriptions or access to the admin site. When the information from the next part is published you will probably want to remove a group entry.

To remove a user or a group

Remove-MgmtSvcAdminUser –Principal DOMAIN\<username or groupname>GROUPNAME -ConnectionString $Connectionstring

Have fun implementing ADFS with Windows Azure Pack. I’m curious to hear what more advanced scenarios you have designed or possible issues you run in. See you for the next part that will look at the content of the actual claims. In the meanwhile follow me on twitter @_marcvaneijk