5

Our client would like for us to utilize ADFS 2012 R2 (aka 3.0) as the primary means for two security features in internal apps that we are building:

  1. The web app (there are two .NET & Angular) and an iOS app will use the OAUTH flow within ADFS
  2. Upon completion of the token flow, the JWT created by ADFS will be passed to a RESTful API that is being created with Spring
  3. The Spring API will then need to validate the JWT before allowing the call to proceed

Using ADFS for the OAUTH flow is new to us and a few questions have popped up. We've scoured the Internets looking for answers. Many of them are singly focused on delivering a solution using MS only tech (ADAL, .NET/C# based APIs, OWIN, Katana). Thus, we hoped to crowd-source an answer via SE. Any and all help is much appreciated.

At this point, we have been able to:

  • Register an OAUTH client with the PowerShell command in ADFS
  • Register a "fake" Resource as a Relying Party in ADFS
  • Setup our clients to make a call to ADFS to authorize and then get the returned JWT

This link was very helpful in explaining the setup:

http://blogs.technet.com/b/askpfeplat/archive/2014/11/03/adfs-deep-dive-comparing-ws-fed-saml-and-oauth-protocols.aspx

Now, we need to put the code in place in the Spring API to verify the JWT.

In all examples of OAUTH flow, there is a shared secret between the issuing party and the client. This secret is used to verify that the JWT has not been spoofed.

In the setup we have done thus far in ADFS, there is no definition of a secret key or shared secret. We can grab the JWT from the authorization header and decode it. But we seem to have no means to verify the signature.

The question is how do we validate the JWT within the Spring API (passed from the client via the header) that comes back from ADFS without having the "secret" that was used to build the signature?

Our options if we do not get this to work are:

  • Use Oracle Identity Manager / Access Manager (already in-house)
  • Bring WSO2 Identity Manager into the picture
soglm
  • 51
  • 1
  • 1
  • 3
  • 1
    Can you clarify what your question is? The *"Are we missing something here?"* is a little vague. – RoraΖ Jan 26 '15 at 20:19
  • The question is how do we validate the JWT that comes back from ADFS without having the "secret" that was used to build the signature? *note: Updated the original post as well* – soglm Jan 26 '15 at 21:11
  • If this is an API question on software development, please delete this question and repost on StackOverflow.com – makerofthings7 Jan 26 '15 at 21:42
  • The issue is more narrow than just software dev. We have experience in verifying the JWT with other OAUTH IDPs (i.e. Twitter, FB, Google). The issue here is specific to doing this with ADFS 2012 R2. It appears that ADFS does not fully support OAUTH. We're looking to see if anyone else has implemented JWT validation with this "stack": ADFS 2012 R2, Java Spring API, – soglm Jan 26 '15 at 22:30

3 Answers3

2

I've been trying to answer this same question for the last couple of days. It seems that the Windows Server 2012 R2 ADFS 3.0 implementation of OAUTH2 requires the use of certificates instead of a shared secret if you want to encrypt/sign the JWT response. Having used OAUTH2 with multiple non-Microsoft web applications, I've always seen shared secrets and not certificates. I'd bet that the OAUTH2 standard allows for either, but Microsoft chose to go with what they know in their first implementation of the standard.

So far, I've seen one quote from a Microsoft employee blog that makes me think what we see as "standard" OAUTH2 isn't supported by ADFS 3.0:

From http://blogs.technet.com/b/maheshu/archive/2015/05/26/json-web-token-jwt-support-in-adfs.aspx

JWTs issued by ADFS on Windows Server 2012 R2 are signed using ADFS' issuing certificate. ADFS does not support JWT encryption.

Also, the What's New in ADFS for Windows Server 2016 points out that shared secrets are going to be a new feature:

(Sorry for the non-link links. Since I have no reputation here, I can only include one link in this post.) From technet.microsoft.com/en-us/library/mt617220.aspx (Emphasis mine.)

AD FS for Windows Server 2016 builds upon the Oauth protocol support that was introduced in Windows Server 2012 R2, to enable the most current and industry standard based authentication flows among web apps, web APIs, browser and native client based apps. Windows Server 2012 R2 offered support for the Oauth authorization grant flow and authorization code grant type, for public clients only. In Windows Server 2016, the following additional protocols and features are supported:

  • OpenId Connect support
  • Additional Oauth authorization code grant types
    • Implicit flow (for single page applications)
    • Resource Owner password (for scripting apps)
  • Oauth confidential clients (clients capable of maintaining their own secret, such as app or service running on web server)
  • Oauth confidential client authentication methods
    • Symmetric ( shared secret / password)
    • Asymmetric keys
    • Windows Integrated Authentication (WIA)
  • Support for "on behalf of" flows as an extension to basic Oauth support.

For more see Enabling Oauth Confidential Clients with AD FS 2016 and Enabling OpenId Connect with AD FS 2016

As a developer, setting up an IIS box in the domain with a handler page (ASHX) that verifies the domain user and redirects the user back to the web app with a JWT that is encrypted using the shared key is a simple solution until Windows Server 2016 is available. We have sample code on how to do this on our application's forum: connectionsonline.zendesk.com/entries/82271995-Single-Sign-on-Authentication-SSO-with-OAuth-2-0

bts
  • 121
  • 3
2

If I understand your question correctly, the signature is a RSASSA using SHA-256 hash based on the configured Token Signing Certificate.

I've got a Node.js validation example on GitHub and here's a blog post with a few more details.

Chris
  • 121
  • 2
0

If you can get JWT token then life becomes easy by the WebAPI, for C# application the following code can use (Owin nuget package)

app.UseActiveDirectoryFederationServicesBearerAuthentication(
new ActiveDirectoryFederationServicesBearerAuthenticationOptions
{
    Audience = "The AppId Registered In ADFS",
    MetadataEndpoint = "https://fs.domain.com/federationmetadata/2007-06/federationmetadata.xml"
});

see blog securing-a-web-api-with-adfs on windows server 2012-r2 here

Haroon
  • 101