Claims-Based Identity in Windows Azure Pack

Claims fundamentals

This white paper discusses some concepts, such as claims and federated identity, that may sound new but have been around for a long time. Federation protocols such as WS-Federation and the Security Assertion Markup Language (SAML) have existed for many years as interoperable protocols that are implemented on all major technology platforms.

To see the power of claims, you might need to change your view of authentication. It's easy to let a particular authentication mechanism constrain your thinking. If you use Windows® authentication (Kerberos or NTLM), you probably think of identity in terms of Windows user accounts and groups. If you use the ASP.NET membership and role provider, you probably think in terms of user names, passwords, and roles. If you try to determine what the various authentication mechanisms have in common, you can abstract the individual elements of identity and access control into two parts: a single, general notion of claims, and the concept of an issuer or an authority.

A claim is a statement that one subject makes about itself or another subject. The statement can be about a name, identity, key, group, privilege, or capability, for example. Claims are issued by a provider, and they are given one or more values and then packaged in security tokens that are issued by an issuer, commonly known as a security token service (STS).

For a full list of definitions of terms that are associated with claims-based identity, refer to the Appendix section.

Claims decouple your applications from the details of identity. With claims, it's no longer the application's responsibility to authenticate users. All your application needs is a security token from the issuer that it trusts. Your application won't break if the IT department decides to upgrade security and require users to submit a smart card instead of submitting a user name and password. In addition, it won't need to be recoded, recompiled, or reconfigured.

Example

Claims-based identity is all around us. A very familiar analogy is the authentication protocol that you follow each time you visit an airport. You can't simply walk up to the gate and present your passport or driver's license. Instead, you must first check in at the ticket counter. Here, you present whatever credential makes sense. If you're going overseas, you show your passport. For domestic flights, you present your driver's license. After verifying that your picture ID matches your face (authentication), the agent looks up your flight and verifies that you've paid for a ticket (authorization). If all is in order, you receive a boarding pass that you take to the gate.

A boarding pass is very informative. Gate agents know your name and frequent-flyer number (authentication and personalization), your flight number and seating priority (authorization), and perhaps even more. The gate agents have everything that they need to do their jobs efficiently. There is also special information on the boarding pass. It is encoded in the bar code and/or the magnetic strip on the back. This information (such as a boarding serial number) proves that the pass was issued by the airline and is not a forgery. In essence, a boarding pass is a signed set of claims that the airline makes about you. It states that you are allowed to board a particular flight at a particular time and sit in a particular seat. Of course, agents don't need to think very deeply about this. They simply validate your boarding pass, read the claims on it, and let you board the plane.

It's also important to note that there may be more than one way of obtaining the signed set of claims that compose your boarding pass. You might go to the ticket counter at the airport, or you might use the airline's website and print your boarding pass at home. The gate agents don't care how the boarding pass was created. They don't care which issuer you used, as long the airline trusts it. They only care that the boarding pass is an authentic set of claims that give you permission to get on the plane.

In software, this bundle of claims is called a security token. Each security token is signed by the issuer who created it. A claims-based application considers users to be authenticated if they present a valid, signed security token from a trusted issuer. The following diagram shows a typical process of obtaining and using tokens.

Federation fundamentals

Federation allows various claims issuers (security token service or STS) to be chained together to provide identities to an application. As mentioned in the previous section, this allows the application to delegate the task of authenticating the users to an external trusted identity system and implement just the authorization to resources that are native to the application. Users can get access to their federated identities either through the browser or through smart (non-browser) clients.

Browser-based authentication

When a user accesses the application through the browser and without a security token, he or she is redirected to the claims provider, which is also known as the federation service.

The federation service then authenticates the user through one or more methods such as form-based input, smart card, Kerberos, and NTLM. After the issuer authenticates the user, it gathers whatever claims the application needs, packages them into a security token, and signs the token by using its private key. If the application requires encryption on its tokens, the issuer encrypts the token by using the public key in the application's certificate. The issuer now asks the browser to go back to the application. The browser sends the token to the application so that it can process the claims. After the application processes the claims, the user can begin using the application.

Now consider this process from the user's experience. If the issuer uses Windows authentication, the user clicks the link to the application and waits for a moment while the browser is first redirected to the issuer and then back to the application. The user is then signed in without any additional input. If the issuer requires input from the user, such as a user name and password or a smart card, the user must pause briefly to sign in, and then he or she can use the application. From the user's point of view, the sign in process with claims is the same as what he or she is used to, which is critical.

The following diagram shows the flows in a typical browser-based authentication sequence. This example includes an STS and uses Active Directory® Federation Services (AD FS) with Active Directory Domain Services (AD DS) as the identity provider.

Smart-client-based authentication

When you connect to a web service (directly or by invoking a Windows PowerShell® cmdlet indirectly), you are not using a browser. This means that you are not getting the benefits of automatic redirection to the claims issuer and through the entire trust chain. It's also impossible to render a web-based sign in UI, if that's required. Instead, you use an arbitrary client to handle the claim-based identity protocols. This client should include an explicit logic to traverse the entire trust chain.

The steps for a smart client are similar to those for browser-based applications. The smart client makes a round trip to the issuer and requests a security token (RST). After the issuer authenticates the user, it has identified which application is attempting access, and it can determine which claims to issue. Then, the issuer sends back the response. The response includes a signed security token that, if needed, is encrypted with the public key of the application.

Federation across multiple realms

The previous sections discussed how federated identity works within a single realm that describes identity federation between your application and a local issuer in your realm. That relationship doesn't change when your issuer interacts with an issuer that it trusts in a different realm. The only change is that your issuer is now configured to accept a security token that is issued by a partner company instead of directly authenticating users from that company. Your issuer trusts another issuer to authenticate users so it doesn't have to. This is similar to how your application trusts its issuer. The following diagram shows the steps for federating identity across realms.

Federating identity across realms is exactly the same as you've seen in the earlier authentication techniques that this paper discussed, with the addition of an initial handshake in the partner's realm. The process is as follows:

  1. Users authenticate with an issuer in their own realm.
  2. Users present the tokens that they receive from their exchanges to your issuer, which accepts it in lieu of authenticating them directly.
  3. Your issuer can now issue a token for the application to use. This token is what the users send to the application.

In browser-based authentication scenarios, the browser and the underlying authentication protocols handle all the redirects. However, when a smart client is used to get security tokens in a multilevel federated environment, the client must identify the trust chain topology and explicitly make these multiple hops. The client handles the authentication at the end identity provider and the token exchange in every issuer (STS) along the path.

It's possible that every segment of the trust chain is using a different authentication protocol or a different security token format. In the browser-based flow, the browser and the underlying protocols handle all of this. But in the smart-client flow, the client must use the appropriate protocol and use the appropriate token type in every segment of the trust chain.

So when you write a client that must get security tokens in a multilevel federated environment, the client must be capable of making these multiple hops and handle the tokens between hops.

Authentication in the Windows Azure Pack

So far, this paper has discussed claims and federation in general to give you an introduction to these concepts. From here on, this paper will provide a detailed discussion of how federated identity is implemented in Windows Azure Pack for Windows Server and the tools that you can use to handle user authentication. Because the browser and the underlying protocols handle all browser-based authentication transparently, this paper will focus on only the smart-client scenarios. In these scenarios, a deeper knowledge is required to successfully authenticate the end user.

The Windows Azure Pack management layer provides an extensive Representational State Transfer (REST) API and a wide range of Windows PowerShell cmdlets. These provide programmatic access to control and operate the administrative management components.

The API and cmdlets require the caller to be authenticated through a security token that is signed by a trusted source. As mentioned in the previous sections, in the claims-based world, an external entity (STS) provides this token. A trust relationship is established between Windows Azure Pack, which is called a relying party, and this STS. This relationship allows the STS to sign security tokens and allows Windows Azure Pack to verify the authenticity of these tokens.

It's possible to create different topologies in a Windows Azure Pack deployment:

  • You can configure the Windows Azure Pack tenant portal to trust the Windows Azure Pack tenant (membership) authentication site, and you can configure the admin portal to trust the Windows Azure Pack admin (Windows) authentication site. In this example, the tenant (membership) authentication site is the acting identity provider/STS. It is an identity provider because it can verify user names and passwords against a membership store. And it is an STS because after it verifies the user identity, it can issue and sign a security token to identify the user. This also applies for admin authentication site.
  • You can configure the tenant portal and admin portal to trust AD FS. This is the recommended topology for production scenarios. In this topology:
    • It is possible to configure AD FS to authenticate users by their AD DS credentials. In this scenario, AD DS is playing the identity provider role, and AD FS is playing the STS role. Together, they form the identity provider/STS scenario.
    • It is possible to configure AD FS to federate with an external STS. In this scenario, AD FS is playing just the STS role.

The chain of trust between Windows Azure Pack and the final identity provider can be very long. The chain can have unlimited number of STSs between Windows Azure Pack (as the relying party) and the final identity provider.

For authentication, the user must go to the final identity provider/STS to provide his or her credentials. In return, the user gets a token. Every STS in the trust chain must exchange this token for a new token. Finally, the token that the final identity provider/STS issued can be presented to Windows Azure Pack.

Supported identity providers

To provide identities directly to this version of Windows Azure Pack, you can use any third-party STS that satisfies the following conditions:

  • Supports WS-Federation
  • Exposes a WS-Metadata endpoint
  • Is capable of generating JSON Web Token (JWT) tokens with at least UPN and optionally Groups claims

Note: These conditions apply only to the first STS in the chain (closest to Windows Azure Pack). Further nodes in the chain do not need to meet these conditions. They should just be able to interact with the previous and next nodes in the trust chain.

Windows Azure Pack includes the following STSs:

  • Tenant (Membership) Authentication Site
    An ASP.NET membership provider–based identity provider/STS. The tenant user enters his or her user name and password on the sign in page. These credentials are verified in the ASP.NET database of membership providers. The membership provider has an STS header over it that can issue signed JWT security tokens for authorized users. It supports the WS-Federation protocol: Passive Requestor Profile (authentication through the browser) and WS-Trust protocol: Active Requestor Profile (authentication through smart clients).
  • Admin (Windows) Authentication SiteA Windows authentication (Kerberos/NTLM)–based identity provider/STS. This STS picks up the currently signed in user's credentials and issues signed JWT security tokens for authorized users. It supports the WS-Federation protocol for passive flows (authentication through the browser) and the WS-Trust protocol for active flows (authentication through smart clients).

Note: Although, theoretically, these two STSs can be used interchangeably, admin authentication should be used only for the admin authentication site, and tenant authentication should be used only for the tenant authentication site. Interchanging this arrangement will cause tenant scenarios to break. In production deployment scenarios, we highly recommended using AD FS.

Apart from these two sites, AD FS 3.0 can be used to provide tokens and claims to Windows Azure Pack. Earlier versions are not compatible, because they do not support issuing JWT security tokens. The Windows Azure Pack Installation Guide has more information about how to configure the trust between Windows Azure Pack and AD FS. Using AD FS is the recommended way to federate with third-party identity providers.

Authenticating to the Admin and Tenant portals

Browser-based authentication in Windows Azure Pack is based on the WS-Federation Passive Requestor Profile, which describes the same communication flow between the browser and web applications. It relies on browser redirects, HTTP GET, and POST to request and pass around tokens.

In a default installation, the trust between the portals and the authentication sites is readily set up so that when the user tries to access the Admin or Tenant portal, he or she is redirected to the appropriate authentication site where the credentials are validated and a token is sent back. This behavior is similar when other STSs are federated with Windows Azure Pack. The following diagram demonstrates a typical sign in flow to Windows Azure Pack.

Authenticating to the Service Management API layer

Windows Azure Pack also facilities direct interaction with the Service Management API layer. When you make API calls, you must present a security token from a trusted STS. The protocols that you follow to get these tokens depend on the trust chain topology that is part of your Windows Azure Pack installation. After you obtain the security token, you must pass it as a bearer token in the header of the request.

As mentioned earlier, if the client application does not have a browser-based interface, the user must be active and know about every STS in the trust chain and about the final identity provider. The user must access the final identity provider, authenticate himself or herself, and then explicitly go through every STS in the chain (in the right order) and exchange the token. It becomes even more complicated if each STS or identity provider supports a different protocol or a different security token type. The user must be familiar with the entire trust chain topology and approach every identity provider or STS by using the right protocol.

The following sections describe methods that you can use to programmatically access some STSs and identity providers by using the WS-Trust active protocol. All the Windows Azure Pack–recommended identity provider/STS components—AD FS, Windows Azure Pack Tenant (Membership) Authentication Site, and Windows Azure Pack Admin (Windows) Authentication Site—support the WS-Trust protocol.

Windows PowerShell cmdlet

The Management Service Admin PowerShell module is installed as a part of Windows Azure Pack. You can use the Get-MgmtSvcToken
cmdlet to get a token. This is possibly the easiest way to get identity tokens for Windows Azure Pack.

The Get-MgmtSvcToken cmdlet has the following syntax:

Get-MgmtSvcToken -Type <Membership | MembershipAdfs | Windows | WindowsAdfs> -AuthenticationSite <Uri> -ClientRealm <Uri> [-AdfsAddress <Uri>] [-AdfsRealm <Uri>] [-DisableCertificateValidation] [-User <PSCredential>] [<CommonParameters>]

The Get-MgmtSvcToken cmdlet creates an identity token. Several of the Windows Azure Pack cmdlets use tokens. You can create a token and store it in a variable for use with other cmdlets.

Parameters

-AdfsAddress<Uri>

Specifies the base address of the AD FS endpoint. Use the following format: https://computer:port. For example: https://adfs.contoso.com. This parameter is only required when AD FS is used in the trust chain (when the target is set to MembershipAdfs or WindowsAdfs).

Aliases

None

Required?

False

Position?

named

Default Value

none

Accept Pipeline Input?

True (ByPropertyName)

Accept Wildcard Characters?

False

-AdfsRealm<Uri>

Specifies the AD FS realm. This parameter is required only when AD FS is used in the trust chain (when the target is set to MembershipAdfs or WindowsAdfs). You can retrieve it by invoking the (Get-AdfsProperties).Identifier cmdlet at an AD FS Windows PowerShell command prompt.

Aliases

none

Required?

false

Position?

named

Default Value

none

Accept Pipeline Input?

True (ByPropertyName)

Accept Wildcard Characters?

false

-AuthenticationSite<Uri>

Specifies the Uniform Resource Identifier (URI) of the authentication site. Use the following format: https://computer:port. For example: https://Computer01:30072.

Aliases

none

Required?

true

Position?

2

Default Value

none

Accept Pipeline Input?

True (ByPropertyName)

Accept Wildcard Characters?

false

-ClientRealm<Uri>

Specifies the client realm that identifies the requesting application. Possible values are: http://azureservices/TenantSite (for tenant requests) and http://azureservices/AdminSite (for admin requests).

Aliases

none

Required?

true

Position?

3

Default Value

none

Accept Pipeline Input?

True (ByPropertyName)

Accept Wildcard Characters?

false

-DisableCertificateValidation

Disables certificate validation in accessing remote STS endpoints. You should not use this parameter in production environments, because all endpoints should use trusted Secure Sockets Layer (SSL) certificates. By specifying this parameter, you can use self-signed SSL certificates.

Aliases

none

Required?

false

Position?

named

Default Value

none

Accept Pipeline Input?

false

Accept Wildcard Characters?

false

-Type <TokenType>

Specifies the topology of the trust chain. Valid values are:

  • Windows
  • WindowsAdfs
  • Membership
  • MembershipAdfs

Aliases

none

Required?

true

Position?

1

Default Value

none

Accept Pipeline Input?

True (ByPropertyName)

Accept Wildcard Characters?

false

-User <PSCredential>

Specifies a user account and password as a PSCredential object. To create a PSCredential object, use the Get-Credential cmdlet.

Aliases

none

Required?

false

Position?

named

Default Value

none

Accept Pipeline Input?

True (ByPropertyName)

Accept Wildcard Characters?

false

<CommonParameters>

The Get-MgmtSvcToken cmdlet supports the common parameters: -Verbose, -Debug, -ErrorAction, -ErrorVariable, -OutBuffer, and -OutVariable. For more information, see about_CommonParameters.

The limitation of using this cmdlet, though, is that it supports only a limited number of deployment configurations. In your production environment, you might have different identity providers or STSs that support different protocols or security token types. So the following sections describe the effort that's required to make such a cmdlet.

Several of the Windows Azure Pack cmdlets use tokens. You can create a token and store it in a variable for use with other cmdlets. Typically, the admin authentication site and tenant authentication site are installed at ports 30072 and ports 30071, respectively.

$cred = Get-Credential

$token = Get-MgmtSvcToken -Type Windows `
-AuthenticationSite "https://wap01.contoso.com:30072" ` # if you have reconfigured your Authentication site to a different URI, use that instead, e.g., https://adminauth.contoso.com
-ClientRealm "http://azureservices/AdminSite" `
-User $cred `


-DisableCertificateValidation

The ClientRealm parameter is used to uniquely identify a relying-party application that's registered with an STS. In a Windows Azure Pack installation, the admin portal and the tenant portal are the registered relying-party applications. So when you're getting a token, what you're really doing is telling the STS to provide a security token that is targeted to the tenant portal, the admin portal, or the underlying API. The following table specifies default values for the admin and tenant realms. These realms can be changed after installation.

Relying-party application

ClientRealm value

Windows Azure Pack admin portal

http://azureservices/AdminSite

Windows Azure Pack tenant portal

http://azureservices/TenantSite

The $token contains the security token that can be used in the following requests that are made to the API layer.

Coding or scripting your own method of token requisition

If the Get-MgmtSvcToken cmdlet does not satisfy your trust chain topology, you can programmatically create your own trust chains and invoke token requests. This section will show how to perform WS-Trust token requests by using either C# or Windows PowerShell.

Windows Azure Pack provides several Windows PowerShell scripts that demonstrate how to acquire tokens in some common topologies. You can modify these scripts as necessary to support different trust chain topologies. You can find the scripts at:

%ProgramFiles%\Management Service\MgmtSvc-PowerShellAPI\Samples\Authentication\

The Get-TokenWindows.ps1 script in that folder performs the same operation as the cmdlet example that was mentioned previously. The sample scripts use Microsoft .NET Framework 4.5 Windows Communication Foundation (WCF) objects to abstract the WS-Trust protocol implementation. Before you read a detailed explanation of the scripts, you might want to become familiar with some of the terminology.

Endpoints

Most STSs, including the Windows Azure Pack–supported STSs, expose more than one WS-Trust endpoint. These endpoints differ from each other by the inputs that they accept and by the security protocols that are used to deliver requests and responses.

Some endpoints accept a user name and password to authenticate a user. Other endpoints accept the user's Kerberos token to validate the user, or they accept a trusted security token as input.

Some endpoints use transport security—for example, an HTTP over SSL (HTTPS) or Transport Layer Security (TLS) connection. Others use message security, like encrypting the actual SOAP messages that are passing on the wire. Some require both transport and message security. The following table lists the various endpoints that various components in Windows Azure Pack expose.

Endpoint

Component

Client credential type

Security mode

username

Tenant authentication site

UserName

Includes credentials in the message and uses message security

usernamemixed

Tenant authentication site

UserName

Includes credentials in the message and uses transport security

windows

Admin authentication site

Windows

Includes credentials in the message and uses message security

windowstransport

Admin authentication site

Windows

Includes credentials in the transport layer and uses transport security

WCF ChannelFactory and bindings

As mentioned before, acquiring a token requires providing credentials to an identity provider/STS and then going through the entire trust chain to translate the token. Each hop in the trust chain might use a different protocol, or it might use the same protocol but with different security settings. WCF provides different binding classes that are used to define a single hop in terms of the protocol that is used, the type of token that is used, and the security settings, such as transport and message security details.

WCF provides several classes to help with the process of acquiring tokens and abstracting the underlying implementation details of the WS-* protocols. The major components are:

  • WSTrustChannelFactory
    The WSTrustChannelFactory class is used to create WS-Trust channels, and to invoke token requests by using the defined binding chain.
  • WS2007HttpBinding
    The WS2007HttpBinding class is used to define the security requirements of a single hop in the trust chain.
  • WS2007FederationHttpBinding
    The WS2007FederationHttpBinding class does the same thing as the WS2007HttpBinding class, but it also provides a way to chain requests together.

By using a single WS2007HttpBinding class and zero or more WS2007FederationHttpBinding classes, you can describe a full trust chain (assuming that all hops in the trust chain support WS-Trust). Otherwise, you should use other bindings (or other means) to acquire and exchange security tokens in order to support other protocols and token types.

You start by importing the necessary references. For this script, you need the System.ServiceModel and System.IdentityModel namespaces, both version 4.0.0.0.

Windows PowerShell

Add-Type -AssemblyName 'System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

Add-Type -AssemblyName 'System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

C#

After you add a reference to System.IdentityModel and System.ServiceModel to your project

using System.IdentityModel.Tokens;

using System.ServiceModel;

You must now define the security endpoint of the end identity provider and its credential requirements—for example, whether user name and password are used to authenticate the user or whether Windows authentication is used. You should also create a matching WS2007HttpBinding.

For example, if you're providing a user name and password to the tenant authentication site, you should use the "usernamemixed" endpoint as follows.

Windows PowerShell

$authSiteAddress = "https://<your tenant fqdn and port>"

$identityProviderEndpoint = New-Object -TypeName System.ServiceModel.EndpointAddress -ArgumentList ($authSiteAddress + '/wstrust/issue/usernamemixed')

$identityProviderBinding = New-Object -TypeName System.ServiceModel.WS2007HttpBinding -ArgumentList ([System.ServiceModel.SecurityMode]::TransportWithMessageCredential)

$identityProviderBinding.Security.Message.EstablishSecurityContext = $false

$identityProviderBinding.Security.Message.ClientCredentialType = 'UserName'

$identityProviderBinding.Security.Transport.ClientCredentialType = 'None'

C#

var authSiteEndPoint = "https://<your tenant fqdn and port>"

var identityProviderEndpoint = new EndpointAddress(new Uri(authSiteEndPoint + "/wstrust/issue/usernamemixed"));

var identityProviderBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential);

identityProviderBinding.Security.Message.EstablishSecurityContext = false;

identityProviderBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

identityProviderBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

The identityProviderBinding
specifies the type of security that you want to use for sending a request. Notice that in the above snippet we define the Security mode of the Binding to be SecurityMode.TransportWithMessageCredential because the endpoint is a 'mixed' endpoint (derived from the name 'usernamemixed') which implies that we are mixing Message and transport Security. The message ClientCredentialType is specified UserName for the same reason. You can also use the "username" endpoint to perform just message security by changing the SecurityMode to SecurityMode. Message.

When AD FS is configured to use AD DS for authentication, it can also accept a user name and password for authentication if you use the "usernamemixed" endpoint. Note that by default, most of the AD FS endpoints are disabled, so you must make sure that this endpoint is enabled (and the AD FS service is restarted) before you try to access this endpoint.

Windows PowerShell

$adfsAddress = "https://<your AD FS fqdn and port>"

$identityProviderEndpoint = New-Object -TypeName System.ServiceModel.EndpointAddress -ArgumentList ($adfsAddress + '/adfs/services/trust/13/usernamemixed')

$identityProviderBinding = New-Object -TypeName System.ServiceModel.WS2007HttpBinding -ArgumentList ([System.ServiceModel.SecurityMode]::TransportWithMessageCredential)

$identityProviderBinding.Security.Message.EstablishSecurityContext = $false

$identityProviderBinding.Security.Message.ClientCredentialType = 'UserName'

$identityProviderBinding.Security.Transport.ClientCredentialType = 'None'

C#

var adfsEndPoint = "https://<your AD FS fqdn and port"

var identityProviderEndpoint = new EndpointAddress(new Uri(adfsEndPoint + "/adfs/services/trust/13/usernamemixed"));

var identityProviderBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential);

identityProviderBinding.Security.Message.EstablishSecurityContext = false;

identityProviderBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

identityProviderBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

Note that the bindings used here are exactly the same as the ones used in the previous snippet.

The Admin authentication site uses Windows authentication and so you specify the "windowstransport" endpoint.

Windows PowerShell

$authSiteAddress = "https://<your admin fqdn and port>"

$identityProviderEndpoint = New-Object -TypeName System.ServiceModel.EndpointAddress -ArgumentList ($authSiteAddress + '/wstrust/issue/windowstransport')

$identityProviderBinding = New-Object -TypeName System.ServiceModel.WS2007HttpBinding -ArgumentList ([System.ServiceModel.SecurityMode]::Transport)

$identityProviderBinding.Security.Message.EstablishSecurityContext = $false

$identityProviderBinding.Security.Message.ClientCredentialType = 'None'

$identityProviderBinding.Security.Transport.ClientCredentialType = 'Windows'

C#

var windowsAuthSiteEndPoint = "https://<your admin fqdn and port>"

var identityProviderEndpoint = new EndpointAddress(new Uri(windowsAuthSiteEndPoint + "/wstrust/issue/windowstransport"));

var identityProviderBinding = new WS2007HttpBinding(SecurityMode.Transport);

identityProviderBinding.Security.Message.EstablishSecurityContext = false;

identityProviderBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;

identityProviderBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

Notice that in the above snippet we are defining the Security mode of the Binding to be SecurityMode.Transport because the endpoint is a 'transport' endpoint (derived from the name 'windowstransport') which implies that we are using Transport Security. The Transport ClientCredentialType is specified as Windows for the same reason.

At this point, if the Admin authentication site or Tenant authentication site is the identity provider, and Windows Azure Pack is configured to trust these directly, this binding defines the entire trust chain and no other binding definition is necessary. If any of the identity providers are chained through another STS—AD FS, for instance—you must define additional WS2007FederationHttpBinding classes to specify the security requirements, the WS-Trust endpoints, and then add them to your existing trust chain. If the chain contains multiple nodes, you must define a WS2007FederationBinding class for each node. The following code serves as an example for mixed mode authentication with SHA-256 symmetric-key encryption, when you use AD FS as an intermediary STS.

Windows PowerShell

$federationEndpoint = New-Object -TypeName System.ServiceModel.EndpointAddress -ArgumentList ($adfsAddress + '/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256sha256')

$adfsRealm = "<AD FS identity (can be retrieved by invoking (Get-AdfsProperties).Identifier)>"

$xml = New-Object -TypeName System.Xml.XmlDocument

$xml.LoadXml('<wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"><wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsa:Address>' + $adfsRealm + '</wsa:Address></wsa:EndpointReference></wsp:AppliesTo>')

$federationBinding = New-Object -TypeName System.ServiceModel.WS2007FederationHttpBinding -ArgumentList ([System.ServiceModel.WSFederationHttpSecurityMode]::TransportWithMessageCredential)

$federationBinding.Security.Message.EstablishSecurityContext = $false

$federationBinding.Security.Message.IssuedKeyType = 'SymmetricKey'

$federationBinding.Security.Message.AlgorithmSuite = 'Basic256Sha256'

$federationBinding.Security.Message.NegotiateServiceCredential = $false;

$federationBinding.Security.Message.TokenRequestParameters.Add($xml.DocumentElement);

$federationBinding.Security.Message.IssuerAddress = $identityProviderEndpoint;

$federationBinding.Security.Message.IssuerBinding = $identityProviderBinding;

$federationBinding.Security.Message.IssuedTokenType = 'urn:oasis:names:tc:SAML:2.0:assertion'

C#

var federationEndpoint = new EndpointAddress(new Uri(adfsEndpoint + "/adfs/services/trust/13/issuedtokenmixedasymmetricbasic256sha256"));

var xml = new XmlDocument();

xml.LoadXml(@"<wsp:AppliesTo xmlns:wsp=""http://schemas.xmlsoap.org/ws/2004/09/policy""><wsa:EndpointReference xmlns:wsa=""http://www.w3.org/2005/08/addressing""><wsa:Address>http://kc-adfs.katalcloud.com/adfs/services/trust</wsa:Address></wsa:EndpointReference></wsp:AppliesTo>");

var federationBinding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);

federationBinding.Security.Message.EstablishSecurityContext = false;

federationBinding.Security.Message.IssuedKeyType = SecurityKeyType.AsymmetricKey;

federationBinding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Basic256Sha256;

federationBinding.Security.Message.NegotiateServiceCredential = false; federationBinding.Security.Message.TokenRequestParameters.Add(xml.DocumentElement);

federationBinding.Security.Message.IssuerAddress = identityProviderEndpoint;

federationBinding.Security.Message.IssuerBinding = identityProviderBinding;

federationBinding.Security.Message.IssuedTokenType = "urn:oasis:names:tc:SAML:2.0:assertion";

The preceding code describes the AD FS endpoint that is used to exchange the security token that was retrieved from the previous STS. (In this case, it's the identity provider.) The code describes the endpoint transport and message security requirements for the exchange, including the encryption type and algorithm to be used. (In this case, you use an endpoint that requires message encryption.) For other endpoints that have different security requirements, this code must be customized based on the STS that you're using.

The preceding code is also where you define the chaining of bindings that form the trust chain. You do so by using the IssuerAddress, IssuerBinding, and IssuerTokenType parameters to WS2007FederationBinding. This will allow the WSTrustChannelFactory class to traverse the entire trust chain by following this linked list of federated bindings.

After this, all you need to do is to set up WSTrustChannelFactory and invoke the request by using the bindings that were formed earlier. If you have only one identity provider or STS, you need to use only the WS2007HttpBinding class that you defined previously, as follows.

Windows PowerShell

$trustChannelFactory = New-Object -TypeName System.ServiceModel.Security.WSTrustChannelFactory -ArgumentList $identityProviderBinding, $identityProviderEndpoint

$trustChannelFactory.TrustVersion = [System.ServiceModel.Security.TrustVersion]::WSTrust13

C#

var trustChannelFactory = new WSTrustChannelFactory(identityProviderBinding, identityProviderEndpoint)

{

TrustVersion = TrustVersion.WSTrust13,

};

If you defined a chain of bindings (describing a more complex trust chain), you must provide the last WS2007FederationHttpBinding class in the chain to the WSTrustChannelFactory class as follows.

Windows PowerShell

$trustChannelFactory = New-Object –TypeName System.ServiceModel.Security.WSTrustChannelFactory -ArgumentList $federationBinding, $federationEndpoint

$trustChannelFactory.TrustVersion = [System.ServiceModel.Security.TrustVersion]::WSTrust13

C#

var trustChannelFactory = new WSTrustChannelFactory(federationBinding, federationEndpoint)

{

TrustVersion = TrustVersion.WSTrust13,

};

Note that the WS-Trust version that AD FS (for the endpoints mentioned above), the tenant authentication site, and the admin authentication site support is WS-Trust 1.3.

Optionally, you can choose to disable certificate validation. You should use this option only in development and test environments where the system might be set up through self-signed certificates. When this option is deployed in a production environment, you should use certificates from a trusted certificate authority.

Windows PowerShell

if ($allowSelfSignCertificates)
{
$certificateAuthentication = New-Object -TypeName System.ServiceModel.Security.X509ServiceCertificateAuthentication  
$certificateAuthentication.CertificateValidationMode = 'None'
$trustChannelFactory.Credentials.ServiceCertificate.SslCertificateAuthentication = $certificateAuthentication

}

C#

if (certificateValidation == CertificateValidation.Disable)
{
trustChannelFactory.Credentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication() { CertificateValidationMode = X509CertificateValidationMode.None};
}
  

If the identity provider endpoint that you are using requires explicit credentials, like user name and password or client certificate, you must provide these credentials to WSTrustChannelFactory. For example, if the selected endpoint is "usernamemixed," you should provide the user name and password as follows.

Windows PowerShell

$trustChannelFactory.Credentials.SupportInteractive = $false
$trustChannelFactory.Credentials.UserName.UserName = $username
$trustChannelFactory.Credentials.UserName.Password = $password

C#

trustChannelFactory.Credentials.SupportInteractive = false;
trustChannelFactory.Credentials.UserName.UserName = userName;
trustChannelFactory.Credentials.UserName.Password = password;
  

You are now ready to send the request. You send the request by creating a WSTrustChannel object, invoking the Issue command, and passing a RequestSecurityToken object on this channel, as follows.

Windows PowerShell

$channel = $trustChannelFactory.CreateChannel()
$rst = New-Object -TypeName System.IdentityModel.Protocols.WSTrust.RequestSecurityToken -ArgumentList ([System.IdentityModel.Protocols.WSTrust.RequestTypes]::Issue)
$rst.AppliesTo = New-Object -TypeName System.IdentityModel.Protocols.WSTrust.EndpointReference -ArgumentList $clientRealm
$rst.TokenType = 'urn:ietf:params:oauth:token-type:jwt'
$rst.KeyType = [System.IdentityModel.Protocols.WSTrust.KeyTypes]::Bearer
$rstr = New-Object -TypeName System.IdentityModel.Protocols.WSTrust.RequestSecurityTokenResponse
$token = $channel.Issue($rst, [ref] $rstr);

C#

var channel = trustChannelFactory.CreateChannel();
var rst = new RequestSecurityToken(RequestTypes.Issue){
AppliesTo = new EndpointReference(clientRealm),
TokenType = "urn:ietf:params:oauth:token-type:jwt",
KeyType = KeyTypes.Bearer,
};
RequestSecurityTokenResponse rstr = null;
SecurityToken token = null;
token = channel.Issue(rst, out rstr);
   

This RequestSecurityToken object defines the final expected token type. It follows the Windows Azure Pack requirements by asking the security token type to be the JWT bearer token, and it specifies the client realm to be used (admin or tenant). The RequestSecurityTokenResponse object contains the returned token, wrapped in WS-Trust XML. To extract the token from this XML, use the following code.

Windows PowerShell

$tokenString = ([System.IdentityModel.Tokens.GenericXmlSecurityToken]$token).TokenXml.InnerText;
$result = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($tokenString));
return $result
  

C#

var tokenString = (token as GenericXmlSecurityToken).TokenXml.InnerText;
var jwtString = Encoding.UTF8.GetString(Convert.FromBase64String(tokenString));
return jwtString;
  

Conclusion

The goal of this document was to explain a typical WS-Trust flow that's required to obtain a security token in Windows Azure Pack. We hope that based on this information, you'll be able to make the required modifications to support your custom trust chain topologies.

Appendix

The following terms are related to claims-based identity.

Term

Definition

Claim

A statement that one subject makes about itself or another subject. For example, the statement can be about a name, identity, key, group, privilege, or capability. Claims are issued by a provider, and they are given one or more values and then packaged in security tokens that are issued by a security token service (STS). They are also defined by a claim value type and, possibly, associated metadata.

Claim name

A user-friendly name for the claim type.

Claim type

The type of statement in the claim. Examples of claim types include first name, role, and email address. The claim type provides context for the claim value, and it is usually expressed as a Uniform Resource Identifier (URI). For example, if the claim type is email address, it is represented as http://schemas.microsoft.com/ws/2008/06/identity/claims/email.

Claim value

The value of the statement in the claim. For example, if the claim type is role, a value might be contributor. If the claim type is first name, a value might be Matt.

Claims-aware application

A relying-party software application that uses claims to manage identity and access for users.

Claims provider

A software component or service that can be used to issue one or more claims during sign-in operations.

Identity provider

A type of claims provider that provides single sign-on functionality between an organization and other claims providers and relying parties.

Identity provider security token service or relying-party security token service

A software component or service that an identity provider uses to accept tokens from a federation partner, and then generate claims and security tokens on the contents of the incoming security token into a format that the relying party can consume. A security token service (STS) receives security tokens from a trusted federation partner or claims provider. Then, the relying-party STS issues new security tokens that a local relying-party application will consume.

Relying party

An application that relies on and uses claims in security tokens that a claims provider issues. For example, an online auction website organization might receive a security token that contains claims that determine whether a subject can access all or part of a relying-party application.

Relying-party application

Software that can consume claims to make authentication and authorization decisions. The relying-party application receives the claims from a claims provider.

Security token

An on-the-wire representation of claims that the issuer of the claims signs cryptographically. This signing provides strong proof to any relying party about the integrity of the claims and the identity of the issuer.

Security token service (STS)

A web service that issues claims and packages them in encrypted security tokens. It is used by a claims provider that issues claims and packages them in security tokens.

trust establishment

A process by which trust relationships are established between claims providers and relying-party applications. This process involves the exchange of identifying certificates that enable the relying party to trust the contents of claims that the claims provider issues.

WS-Federation

The Organization for the Advancement of Structured Information Standards (OASIS) standard specification that defines the WS-Federation Passive protocol and other protocol extensions that are used for federation. The WS-Federation standard defines mechanisms that are used to enable identity, attribute, authentication, and authorization federation across different trust realms. For more information about WS-Federation, see Understanding WS-Federation.

WS-Federation Passive

The protocol for requesting claims from a claims provider by using HTTP web browser redirects. This protocol is described in section 13 of the WS-Federation 1.2 specification.

WS-Federation Passive Requester Profile

A profile that describes how the cross-trust realm identity, authentication, and authorization federation mechanisms that are defined in WS-Federation can be used by passive requesters, such as web browsers, to provide identity services. Passive requesters of this profile are limited to the HTTP protocol. For more information about the WS-Federation Passive Requester Profile, see WS-Federation: Passive Requestor Profile.

WS-Trust

A standard that uses WS-Security to provide web services with methods to build and verify trust relationships. For more information about WS-Trust, see OASIS Web Services Secure Exchange (WS-SX) TC.