Skip to main content

Federated Authorization Using 3rd Party JWTs

Continuing on the theme of authorization from recent blogs, I've seen several emerging requirements for what you could describe as federated authorization using an offline assertion.  The offline component pertaining to the fact that the policy decision point (PDP), has no prior or post knowledge of the calling user.  All of the subject information and context are self contained in the PDP evaluation request. Eg a request that is using a JSON Web Token for example.

A common illustration could be where you have distinct domains or operational boundaries that exist between the assertion issuer and the protected resources. An example could be being able to post a tweet on Twitter with only your Facebook account, with no Twitter profile at all.

A neat feature of OpenAM, is the ability to perform policy decision actions without having prior knowledge of the subject, or in fact having the subject have a profile in the AM user store.  To do this requires a few neat steps.

Firstly let me create a resource type - for interest I'll make a non-URL based resource based on gaining access to a meeting room.


For my actions, I'll add in some activities you could perform within a meeting room...


Next step is to add in a policy set for my Meeting Room #1 and a policy to allow my External Users access to it.


My subjects tab for my policy is the first slight difference to a normal OpenAM policy.  Firstly my users who are accessing the meeting are external, so will not have a session or entry in the OpenAM profile store. So instead of looking for authenticated users, I switch to check for presented claims.  I add in 3 claims - one to check the issuer (obviously only trusted issuers are important to me....but at this step we're not verifying the issuer, that comes later..), the audience and a claim called Role.  Note the claims checks here are simply string comparators not wild cards and no signature checks have been done.

I next add in some actions that my external users can perform against my meeting room.  As managers, I add in the ability to order food, but they can't use the white board!


So far pretty simple.  However, there is one big thing we haven't done.  That is to verify the presented JWT.  The JWT should be signed by the 3rd party IDP in order to provide authenticity of the initial authentication.  For further info on JWT structure see RFE7519 -  but basically there are 3 components, a header, payload and signature.  The header contains algorithm and data structure information, the payload the user claims and the signature a crypto element.  This creates a base64 encoded dot-delimited payload.  However...we need to verify the JWT is from the issuer we trust.  To do this I create a scripted policy condition that verifies the signature.


This simply calls either a Groovy or JavaScript that I create in the OpenAM UI or upload over REST.


The script basically does a check to make sure a JWT is present in the REST PDP call, strips out the various components and creates a corresponding signature based on a shared secret.  If the reconstructed signature matches the submitted JWT signature we're in business.

The script calls in the ForgeRock JSON, JSE, JWS and JWT libraries that are already being used throughout the product, so we're not having to recreate anything new here.

To test the entire flow, you need to create a JWT with the appropriate claims from a 3rd party IDP. There are lots of online generators that can do this.  I used this one to build my JWT.


Note the selection of the algorithm and key.  The key is needed in the script on the AM side.

I can now take my newly minted JWT and make the appropriate REST call into OpenAM.


The call sends a request into ../json/policies?_action=evaluate with my payload of the resource I'm trying to access and my JWT (note this is currently submitted both within the subject.jwt attribute and also the environment map due to OPENAM-8893).  In order to make the call - remember my subject doesn't have a session within OpenAM - I create a service account called policyEvaluator that I use to call the REST endpoint with the appropriate privileges.

A successful call results in access to the meeting room, once my JWT has been verified correctly:


If the signature verification fails I am given an advice message:


Code for the policy script is available here.

NB - the appropriate classes and also the primitive byte[], need to be added the the Java white list for the policy engine, within the global configuration,

Comments

Popular posts from this blog

WebAuthn Authentication in AM 6.5

ForgeRock AccessManagement 6.5, will have out of the box integration for the W3C WebAuthn. This modern “FIDO2” standard allows cryptographic passwordless authentication – integrating with a range of native authenticators, from USB keys to fingerprint and facial recognition systems found natively in many mobile and desktop operating systems.
Why is this so cool? Well firstly we know passwords are insecure and deliver a poor user experience. But aren’t there loads of strong MFA solutions out there already? Well, there are, but many are proprietary, require complex integrations and SDK’s and ultimately, don’t provide the level of agility that many CISO’s and application designers now require. 
Rolling out a secure authentication system today, will probably only result in further integration costs and headaches tomorrow, when the next “cool” login method emerges.
Having a standards based approach, allows for easier inter-operability and a more agile platform for change.
AM 6.5 has int…

OAuth2 With Contextual Binding

I've blogged a few times regarding the trend of implementing Zero Trust and CARTA (Continuous Adaptive Risk and Trust Assessment) style journeys during typical Web single sign on flows.  I want to riff on that process a little, with an update on how to implement something similar for OAuth2/OIDC access tokens.

Why is this important? Well sometimes it is important to apply some context to a particular authorization flow.  Not all access decisions are the same.  Think of the following nuanced situations:

Two users with the same set of scopes, have different API consumption patternsA particular user has downloaded a malicious app which alters the botnet reputation of the request IP addressA particular user has registered their work email address with a site that experienced a credentials breachA media site is behind a paywall and limits access to organisational IP ranges, but a user frequently works in the field These sorts of flows, are a little bit different to the standard Proof of…

Implementing Zero Trust & CARTA within AM 6.x

There is an increasing focus on perimeterless approaches to security design and the buzzy "defensive security architectures".  This blog will take a brief look at implementing a contextual and continuous approach to access management, that can help to fulfil those design aspirations.

The main concept, is to basically collect some sort of contextual data at login time, and again at resource access time - and basically look for differences between the two.  But why is this remotely interesting?  Firstly, big walls, don't necessarily mean safer houses.  The classic firewall approach to security.  Keeping the bad out and the good in.  That concept no longer works for the large modern enterprise.  The good and bad are everywhere and access control decisions should really be based on data above and beyond that directly related to the user identity, with enforcement as close as possible to the protected resource as possible.

With Intelligent AuthX, we can start to collect and s…