AuthorizationServer can be combined with arbitrary authentication methods, but the fact that it comes pre-configured as a WS-Federation relying party, makes it particularly easy to combine it with e.g. ADFS.
This is a really interesting scenario, because it essentially allows adding OAuth2 support to your enterprise authentication infrastructure. And this in turn allows connecting your “modern applications” like HTML/JS, native mobile apps (iOS, Android, Win8/WP8) very easily to your enterprise Web API back ends.
That’s exactly what quite a high percentage of my customers want *today* – e.g. connecting their iPads to a Web API in their AD protected back end. Unfortunately this is not possible with *today’s* available Microsoft products.
AuthorizationServer to the rescue! By adding AS as a relying party to your ADFS you can leverage your existing federated authentication system – and that can range from “simple” IdP-only scenarios to full blown infrastructures containing federation gateways, proxies and (external) federation partners.
Add AuthorizationServer as a relying party to ADFS
The first step is to “register” AS in ADFS. This is a normal relying party registration. Go to Trust Relationships –> Add Relying Party Trust and select Enter data manually.
Choose some display name, e.g. “AuthorizationServer” and don’t select an encryption certificate. Then enable WS-Federation and add the base address of your AS installation as the protocol URL:
On the next screen you have to choose a relying party identifier. That’s up to you, but AS comes pre-configured with urn:authorizationserver. So that’s probably the easiest:
On the issuance authorization rules page you could now configure which domain users get access to AS and thus OAuth2. That’s very nice but I leave that for you as an exercise if needed. By default every domain user will be able to request tokens.
As the last step, you have to add a claim rule that passes the user name to AS. You could use the domain\user format or user@domain. That’s up to you.
Use a pass-through rule for that:
You could also pass other arbitrary claims to AS, but the minimum requirement is a unique user identifier (this will become the sub claim in the access token).
That’s it. One last things since you are already in the ADFS management tool. Later on we need the thumbprint of the ADFS signing certificate. You can get the from Service –> Certificates. Double click the token-signing cert and copy the thumbprint (under Details):
Gotcha: This dialog is a buggy piece of sh**. You wouldn’t believe how often I already pulled my hair because of some “mysterious behaviour”. When you copy from this dialog you also copy some invisible Unicode characters. That means when pasting the thumbprint into web.config, the certificate validation will fail, because the APIs search for the value plus the hidden characters – even when string comparison succeeds. Can drive you crazy. The workaround is to use a text editor like Notepad+ or Sublime to remove the hidden characters (also remove the spaces for good measure)….or just use this great tool from Raffaele: DeployManager.
Connect ADFS to AuthorizationServer
Next you need to connect AS to ADFS. This could be done using the Identity & Access VS Add-in (see the video I linked to above). I am almost always faster changing the configuration manually.
First open configuration\identityModel.services.config in the WebHost project:
If you also used urn:authorizationserver in ADFS then you only need to insert the name of the ADFS server here.
Next open identityModel.config:
<add value="urn:authorizationserver" />
<issuerNameRegistry type=" …ValidatingIssuerNameRegistry, … ">
<add thumbprint="signing_cert_thumbprint" />
<add name="http://adfs_server/adfs/services/trust" />
Here you need to paste in the token signing cert thumbprint and add your ADFS issuer URI. This is typically the above value modulo your ADFS server name. If you are unsure, you can look that up in the ADFS MMC under Federation Service Properties.
If you want to use the OAuth2 resource owner credential flow, you also need to open autofac.config to configured the OAuth2/WS-Trust bridge:
Here you need to configure ADFS’ WS-Trust endpoint (again, typically inserting the server name is sufficient) and also the signing cert thumbprint again.
Now AS is a proper ADFS relying party. The last step would be configure which domain user(s) are AS administrators. You have two options here: either run the initial configuration wizard and enter the user name there, or open the AS configuration database in App_Data and enter the user name into the AuthorizationServerAdministrators table directly.
Make sure you use the same user name format as you configured in ADFS (SAM account name format vs UPN). By default that would be domain\user.
To verify everything is working properly, try the Flows demo project and try out every OAuth2 flow. If everything is fine – you are now able to access AS and the Web API using your domain account – and that’s exactly what we wanted to achieve.
What about ADFS3?
The version of ADFS on soon to be released Windows Server 2012 R2 has built-in OAuth2 support. So you might not need our AuthorizationServer at all. In fact, many companies/admins indeed prefer a supported Microsoft product compared to some OSS project – also the the fact that it is built-into ADFS as opposed to a separate server piece might be easier to manage. ADFS3 also has other features around BYOD that could be useful to you. So if you can deploy Windows Server 2012 R2 this is a viable option.
Nevertheless I still see AuthorizationServer as very valuable and in a number of situations actually far more useful as ADFS OAuth2 support, e.g.
- AS implements all OAuth2 flows – and ADFS3 only code flow (I might be wrong on that one since there is no real documentation right now). But we see a lot of value in the other flows as well – so do our customers.
- AS fully embraces the OAuth2 scope concept – as well as the full authorization model around it (client, scopes, flows etc..). ADFS3 seems to divide its world into resources (== relying parties) and even uses a non-standard protocol parameter for that. There does not seem to be support for scopes at all. We had the same issue when we tried to add OAuth2 to IdentityServer which is a classic IdP – the concepts just don’t mix very well. That’s why we built AS from scratch.
- For many real world scenarios it is actually beneficial that AS and ADFS are separate pieces. ADFS is typically administrated by “Domain Admins” whereas the authorization server logically belongs to the application and thus to “Application Admins”. I’ve seen a lot of friction between those two parties. Separating the concerns makes them often happier.
- AS allows for full customization, e.g. the consent screen. ADFS deliberately moved away from IIS to limit customization.
- AS has a UI for OAuth2. ADFS has PowerShell. sigh.
So to summarize – ADFS in general is a powerful identity provider/federation gateway for Active Directory based networks and user bases. ADFS3 adds “limited” OAuth2 capabilities to it.
AuthorizationServer is a fully featured implementation of OAuth2 – and in combination with ADFS as the authentication back end you get the best of both worlds.