In my last post I described how to authenticate against ACS (The Azure Access Control Service) using the inbuilt username/password store in ACS. In this post I will instead look at authentication using the WS-Trust protocol with ACS being supplied with tokens by ADFS (Active Directory Federation Services). In this scenario a client will be authenticated using their windows credentials in their domain for a service that is outside the domain (ie in the cloud).
Actually, it is a bit unnessecary to go via ACS – you could authenticate straight to ADFS. But personally I find setting up relying parties much easier on ACS, also this would allow you to combine multiple identity providers.
Windows Authentication with ACS/ADFS
Let us look at the underlying steps that we want to reproduce in this example:
- The user tries to access our service (they are currently logged into the domain)
- The binding knows it has to get a token from ADFS using the current credentials
- The binding sends the acquired token to ACS
- The service gets sent the token (along with it’s appropriate claims)
The great thing is that all we have to change from the last post are the binding elements… so lets do that:
<ws2007FederationHttpBinding>
<binding name="serviceBinding">
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false" issuedKeyType="BearerKey" >
<issuerMetadata address="https://test.accesscontrol.windows.net/v2/wstrust/mex" />
<issuer address="https://test.accesscontrol.windows.net/v2/wstrust/13/issuedtoken-symmetric" binding="ws2007FederationHttpBinding" bindingConfiguration="acsBinding" />
<claimTypeRequirements>
<add claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" isOptional="true" />
</claimTypeRequirements>
</message>
</security>
</binding>
<binding name="acsBinding">
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false" issuedKeyType="BearerKey" >
<issuer address="https://adfs.somesite.com/adfs/services/trust/13/windowsmixed" binding="ws2007HttpBinding" bindingConfiguration="adfsBinding" />
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
<ws2007HttpBinding>
<binding name="adfsBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="Windows" establishSecurityContext="false" algorithmSuite="Default" negotiateServiceCredential="true" />
</security>
</binding>
</ws2007HttpBinding>
In this case we have three bindings – the first describes the binding between the client and server. This is an ‘issued token’ type binding (from ACS) so is under ws2007FederationBinding. The next describes the binding between the client and acs, which is also an issued token binding (from ADFS). The final binding describes the binding between the client and adfs. My notes on the above:
- TransportWithMessageCredential/BearerKey – Like the last post I am relying on https transport for my token encryption. So I also set the token type as BearerKey for both of the bindings that rely on issued tokens.
- ClaimTypeRequirements – These are the same in the service binding, but for the acs binding I don’t have to worry about it because ACS and ADFS will work it out on their own.
- IssuerAddress – This have changed in this scenario. Because the ACS is using an issued token we have to use the issuedtoken endpoint address (v2/wstrust/13/issuedtoken-symmetric). For the ADFS endpoint address we will be using windows authentication (over https) so we want to use the windowsmixed endpoint (adfs/services/trust/13/windowsmixed). You could actually do username authentication instead, but then it would not automatically log you in like it does with windows auth.
- clientCredentialType – I chose windows authentication for this blog post so I could illustrate what a windows auth binding to adfs might look like. It is really easy just set the clientCredentialType to “Windows”.
You might already see how all this becomes very composable. For instance if you just wanted to authenticate against ADFS you would drop the ACS binding and have the issuer address of the service binding to point straight to the ADFS endpoint.
So go ahead and change your netTcpBindings to ws2007 bindings and push your application to the cloud just by changing the web.config. You can thank me later ;)