In this article i will go over how to setup your ADFS 3.0 (available in Windows Server 2012 R2) server for OAUTH2 authentication.
A couple of things to note:
- This setup will work for both standalone and farm deployments (including using the WID database). This is because Microsoft build an OAuth Authorization Code Lookup Protocol so that if one server generates the token you can claim it from another in the farm (when using standalone artifact store): https://msdn.microsoft.com/en-us/library/dn409270.aspx
- Make sure you have a basic ADFS configured, there are plenty of guides like this one: https://technet.microsoft.com/en-GB/library/dn486820.aspx
- ADFS 3.0 does not support secrets or token encryption/decryption for OAUTH2
- While OAUTH2 is a standardized protocol i would not call Microsoft implementation a straight forward or standardized solution as there are some specifications.
- If you are using a self-singed certificate please make sure that:
- The Service Communications Certificate has the option of (IsCA = $true), you can use the script from: https://gallery.technet.microsoft.com/scriptcenter/Self-signed-certificate-5920a7c6. This is a must in order for the TLS connection to be established.
- Make sure when you open the certificates in the AD FS console there are no errors
- I have used SHA 256 RSA Certificates and they work great.
!!!Warning!!! – If you use 512 Certificates you will experience issues on ADFS and with OAUTH2.0. You will need to disable TLS1.2 as it doesn’t support 512. You may see errors as show below in the AD FS Admin error log:
Event ID: 36874– TLS 1.2 connection request was received from a remote client application, but none of the cipher suites supported by the client application are supported by the server. The SSL connection request has failed.
Here is some information you will need before we begin:
- ClientID : you can either come up with this or just use a generator like : https://www.guidgenerator.com/online-guid-generator.aspx
- Redirect URI : depending on the application you use and the domain this value will very so please check the application documentation (basically where the browser needs to be redirect after the authentication completes)
- Relaying party identifier: in most cases you will make this up, i recommend using the application domain eg.(https://www.myapp.com)
- The Claims: This would be what values you require to return back to the application, check with the application documentation.
After you are done you will need to make a note of the following things in order to configure your application:
- ClientID
- Redirect URI
- Auth Endpoint : this would be https://myadfs.com/adfs/oauth2/authorize (replace myadfs with whatever domain you have configured)
- Token Endpoint : this would be https://myadfs.com/adfs/oauth2/token (replace myadfs with whatever domain you have configured)
- The public key (the cert without the private key) of the root CA of your Service Communications Certificate. You can export this and add it to your application server Trusted Root Certification Authorities. This is need for a successful TLS communication.
- The public key (the cert without the private key) of your signing certificate. Usually you will need this in PEM or CRT format so you may need to convert it. This will be needed if you or the application you are using needs to verify the JWT token signature (strongly recommended).
Lets go into our ADFS server console and first configure our Relying Party Trust:
Now give our Relying Party Trust a meaningful name
Leave the next section blank as ADFS3 OAuth2 does not support encryption
Again we leave it blank as we don’t use SAML or WS
now we need to enter our Relaying party identifier
If you need multi factor then configure it if not skip it
Once that is done you can configure your Claims (Issuance Transform Rules) whatever they may be
Once done we need to configure our endpoints and we do this via Powershell with the following command:
1
|
Add-AdfsClient -RedirectUri "https://appredirect.local" -ClientId "5d51f771-b86a-419e-ad25-27696eafc02b" -Name "My app entry"
|
We specify some of the variables you collected before hand and then give it a meaningful name
I also recommend you set the option “EnableJWT” to true on the Relying Party Trust you configured by running:
1
|
Set-AdfsRelyingPartyTrust -TargetName "My App" -EnableJWT $true
|
And that should be it, you should be able to now use the OAUTH2 function with your app.
Hi,
Do you know how I can set the Startup class for this in a MVC/Web API project?
Thanks a lot.
Hello Jener,
Unfortunately i am not an expert in MVC/Web API but i think you can link it to adfs directly instead of using oauth2.0:
http://www.cloudidentity.com/blog/2013/10/25/securing-a-web-api-with-adfs-on-ws2012-r2-got-even-easier/
otherwise maybe look at these:
http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api
http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/
Hi,
Thanks for the informative Post. I am developing a Mobile Application. I am unable to figure out what i should fill in as Relaying Party Identifier. Can anyone guide me on this.
Thanks
Sourav
Hello Sourav,
Not a problem mate, basically the Relaying Party Identifier is what ever you wanted it to be. You just need to make sure that when you application make the redirect to ADFS it uses the same Identifier in the redirect as you have specified in ADFS. It’s used as an ID to identify which Party trust it should use. I hope that make sense.
Regards,
Luben
Where do you get the Client ID in the powershell commands towards the end?
Hello Cody,
You generate the Client ID as it needs to be unique, you can use this website: https://www.guidgenerator.com/online-guid-generator.aspx
Regards,
I just tried this out, but ran into an issue. I tried using the Relying Party trust ID specified for the ‘resource’ parameter in the /oauth2/authorize request but got the error: MSIS9602: The received ‘resource’ parameter is invalid. The authorization server can not find a registered resource with the specified identifier.
I then added a second Relying Party trust ID to the setup, and used that as the ‘resource’ parameter and everything works great. It doesn’t appear to like the original value. Is that normal that we can’t use the original ID that was configured and need to use a secondary one?
Hello Jason,
The original ID should work as i have done it many times, the one advice i would have is that it has to match 100%. So if you have spaces at the end or special charecters you don’t knwo about it will throw it off. Bessicly for the reosurce ID and ClientID ADFS jsut runs a compare of what you are sending and whats in the system.
Regards,
Luben
Hello,
Is there a way to pass a relay state parameter to the authorize endpoint? I would use this to redirect the user back to a particular resource they were trying to hit.
I suppose I could put this into a cookie if needed.
Hello Tony,
Sorry for the late reply i just saw your comment, you can pass extra parameters to ADFS and it will return them exactly as you pass them so you don’t need to sue cookies, just make sure the variables you use are different from the standard ADFS once.
I tried your guide, all is good except that I keep getting the following error:
MSIS9321: Received invalid OAuth request. The client ‘*****’ is forbidden to access the resource. How to resolve this? Ive setup Access Control to permit all, then in some blogs it said to set issuance policy instead, but still the same error.
You need to configure the permissions for the client in ADFS 4.0 (Windows 2016). You can do this using the PowerShell – Grant-AdfsApplicationPermission – e.g.:-
Grant-AdfsApplicationPermission -ClientRoleIdentifier “oauth-test-client-id” -ServerRoleIdentifier “oauth-test-resource” -ScopeNames openid
On windows server 2016, you can skip all this and just setup Client and RPT using
Application Group
inside ADFS Console just as mentioned here:https://technet.microsoft.com/en-us/windows-server-docs/identity/ad-fs/development/enabling-oauth-confidential-clients-with-ad-fs-2016
Otherwise, im stuck with events 1020 and 364 (error MSIS9321) forever.
Well done mate i am glad you found a fix, when i initially wrote this it was on a Windows 2012 R2 Server, i guess they have made some changes to 2016.
Hi Luben,
I’m testing ADFS 2016 with OAuth 2.0. I’ve problems to authenticate a native application using grand_type=password and scope=profile, it seems that my app doesn’t have permissions. But I can’t found any option to grant permission for the profile’s scope to my native application.
Could you please help me with that? Thanks
Regards.
You need to configure the permissions for the client in ADFS 4.0 (Windows 2016). You can do this using the PowerShell – Grant-AdfsApplicationPermission – e.g.:-
Grant-AdfsApplicationPermission -ClientRoleIdentifier “oauth-test-client-id” -ServerRoleIdentifier “oauth-test-resource” -ScopeNames openid
This solved it for me. THANKS!
So what would the settings look like after you have configured everything?
using this set up (ADFS 3.0, Oauth 2.0), do we need a WAP (application proxy) in between ADFS and backend application (oauth2 client)?
Hello Radha,
You don’t need a WAP between the application and the ADFS service. It will work with or without it :).
You really only ever need WAP if you are going to expose ADFS externally and thats done for added security.
All internal clients should go directly to the ADFS servers even in a WAP environment.
I hope this make sense to you.
Regards,
Luben
I have noticed you don’t monetize your blog, don’t waste your traffic, you can earn additional bucks every month because
you’ve got hi quality content. If you want to know how to make extra $$$, search for: Mrdalekjd methods for $$$
good article guys, helped me do the needful and at the soonest 🙂
I had a typo in my RedirectUri so as a final step, maybe a sanity check with
Get-AdfsClient -Name “My App”
to display all info and if there are any typos you can pipe this into the set-adfsclient
Get-AdfsClient -Name “My App” | set-adfsclient -RedirectUri “fix typo”
Thanks
Hey there! Thanks for the great piece on setting up Oauth. It’s been very helpful.
However, I’m running into an issue where I’m getting the error:
MSIS9602: The received ‘resource’ parameter is invalid. The authorization server can not find a registered resource with the specified identifier.
Is the resource something that’s defined on the application side and needs to make something within ADFS (like the relying party identifier?) Or is there something in ADFS that contains the resource parameter and that needs to match something on the backend?
We are trying to connect ADFS to Amazon Alexa to utilize Oauth.
Thank you!
Ryan
Hello Team, As per my knowledge, implicit grant flow is not supported by ADFS, please refer to below link for confirmation
https://github.com/nordvall/TokenClient/wiki/OAuth-2-Implicit-Grant-in-ADFS
Due to this, the only supported ‘response_type’ here is ‘code’
How can i get token on client SPA with ‘response_type’ as ‘code’, i receive following error
?error=unsupported_response_type&error_description=MSIS9600%3a+The+authorization+server+does+not+support+obtaining+an+authorization+code+using+the+requested+%27response_type%27.+The+authorization+server+only+supports+%27code%27+as+the+response+type
Are there any additional settings to be done on ADFS to enable this support?
Any response on this will be helpful, Thanks.