Skip to main content

Enhancing OAuth2 introspection with a Policy Decision Point

OAuth2 protection of resource server content, is typically either done via a call to the authorization service (AS) and the ../introspect endpoint for stateful access_tokens, or, in deployments where stateless access_tokens are deployed, the resource server (RS) could perform "local" introspection, if they have access to the necessary AS signing material.  All good.  The RS would valid scope values, token expiration time and so on.

Contrast that to the typical externalised authorization model, with a policy enforcement point (PEP) and policy decision point (PDP).  Something being protected, sends in a request to a central PDP.  That request is likely to contain the object descriptor, a token representing the subject and some contextual data.  The PDP will have a load of pre-built signatures or policies that would be looked up and processed.  The net-net is the PDP sends back a deny/allow style decision which the PEP (either in the form of an SDK or a policy agent) complies with.

So what is this blog about?  Well it’s the juxtaposition of the typical OAuth2 construct, with externalised PDP style authorization.

So the first step is to set up a basic policy within ForgeRock Access Management that protects a basic web URL – http://app.example.com:8080/index.html.  In honesty the thing being protected could be a URL, button, image, physical object or any other schema you see fit.

Out of the box authorization policy summary

To call the PDP, an application would create a REST payload looking something like the following:

REST request payload to PDP
The request would be a POST ../openam/json/policies?_action=evaluate endpoint.  This endpoint is a protected endpoint, meaning it requires authX from an AM instance.  In a normal non-OAuth2 integrated scenario, this would be handled via the iPlanetDirectoryPro header that would be used within the PDP decision.  Now in this case, we don't have an iPlanetDirectoryPro cookie, simply the access_token.

Application Service Account

So, there are a couple of extra steps to take.  Firstly, we need to give our calling application their own service account.  Simply add a new group and associated application service user.  This account could then authenticate either via shared secret, JWT, x509 or any other authentication method configured. Make sure to give the associated group the account is in, privileges to the call the REST PDP endpoint.  So back to the use case...

This REST PDP request is the same as any other.  We have the resource being protected which maps into the policy and the OAuth2 access_token that was generated out of band, presented to the PDP as an environment variable.

OAuth2 Validation Script

The main validation is now happening in a simple Policy Condition script.  The script does a few things: performs a call to the AM ../introspect endpoint to perform basic validation - is the token AM issued, valid, within exp and so on.  In addition there are two switches - perform auth_level validation and also perform scope_validation.  Each of these functions takes a configurable setting.  If performAuthLevelCheck is true, make sure to set the acceptableAuthLevel value.  As of AM 5.5, the issued OAuth2 access_token now contains a value called "auth_level".  This value just ties in the authentication assurance level that has been in AM since the OpenSSO days.  This numeric value is useful to differentiate how a user was validated during OAuth2 issuance. The script basically allows a simple way to perform a minimum acceptable value check.

The other configurable switch, is the performScopeCheck boolean.  If true, the script checks to make sure that the submitted access_token, is associated with atleast a minimum set of required scopes.  The access_token may have more scopes, but it must, as a minimum have the ones configured in the acceptableScopes attribute.

Validation Responses

Once the script is in place lets run through some examples where access is denied.  The first simple one is if the auth_level of the access_token is less than the configured acceptable value.

acceptable_auth_level_not_met advice message

Next up, is the situation where the scopes associated with the submitted access_token fall short of what is required.  There are two advice payloads that could be sent back here.  Firstly, if the number of scopes is fundamentally too small, the following advice is sent back:

acceptable_scopes_not_met - submitted scopes too few

A second response, associated with mismatched scopes, is if the number of scopes is OK, but the actual values don't contain the acceptable ones.  The following is seen:
acceptable_scopes_not_met - scope entry missing

That's all there is to it.  A few things to know.  The TTL of the policy has been set to be the exp of the access_token.  Clearly this is over writable, but seemed sensible to tie this to the access_token lifespan.

All being well though, a successful response back would look something like the following - depending on what actions you had configured in your policy:

Successful PDP response

Augmenting with Additional Environmental Conditions

So we have an OAuth2-compatible PDP.  Cool!  But what else can we do.  Well, we can augment the scripted decision making, with a couple of other conditions.  Namely the time based, IP address based and LDAP based conditions.

IP and Time based augmentation of access_token validation
The above just shows a simple of example of tying the decision making to only allow valid access_token usage between 830am and 530pm Monday-Friday from a valid IP range.  The other condition worth a mention is the LDAP filter one.

Note, any of the environmental conditions that require session validation, would fail, the script isn't linking any access_token to AM session at this point - in some cases (depending on how the access_token was generated) may never have a session associated.  So beware they will not work.

The code for the scripted condition is available here.














Comments

  1. Interesting post. I'd had the same challenge to provide a PEP based on an basic access_token. The situation was the web page was designed to passed the authenticated user's access_token as a request header and we needed to validate it on each request.

    I ended up solving it by routing the web traffic via a route in OpenIG to the back end web server. The route contained a scriptable filter written in Groovy that parsed the access_token out of the request and performed a token introspect call to AM - in almost the exact same way. If the access_token was valid the traffic was reverse proxied, otherwise the user got redirected to a login page - that triggered an OIDC flow.

    It seems to be that AM has two quite distinct authentication paradigms - conventional SSO and the OAuth/OIDC - and there seemed to be not a clear linkage between the two paradigms with regards to session management and policy enforcement etc.

    I hadn't realised this way and it seems a much cleaner approach in that you can tie it in with other policy rules. Not to mention that it elegantly the SSO and OAuth/OIDC paradigms together with regards to a common PDP engine. Very nice.


    ReplyDelete

Post a comment

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…

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…

Forget Passwordless, What About Usernameless?

A year or so ago, I blogged about the wonderful world of passwordless and how WebAuthn was going to save the world!  Gone will be insecure passwords, with their terrible user experience, and contributions to data breaches and in with a standards driven, crypto based, technology agnostic way of authenticating a user. The panacea!  Well, the panacea might just be getting be getting a little better.

Take a look at the above blog for a quick "reccy" on how WebAuthn works and the main flows.  TLDR; we're using public/private key pairs for each website or service we want to authenticate against.  The private key gets stored somewhere safe - namely within the dedicated USB authenticator fob, or within the secure element on an operating system.

In ForgeRock Access Management 7.0 EA, the WebAuthn registration authentication node has been modified to now include a "Username to device" switch.  This essentially allows a user handle to be sent back down to the authenticato…