1 December 2015

Scripted OpenID Connect Claims and Custom JWT Contents

OpenID Connect has been the cool cat on the JSON authorization cat walk for some time.  A powerful extension to the basic authorization flows in OAuth2, by adding in an id_token. The id_token is a JWT (JSON Web Token, pronounced 'jot' but you knew that) that is cryptographically signed and sometimes encrypted - depending on the contents.

The id_token is basically separate to the traditional access_token, containing details such as which authorization service issued the token, when the user or entity authenticated and when the token will expire.

OpenAM has supported implementations for OpenID Connect for a while, but a more recent feature is the ability to add scripting support to the returnable claims.  Adding scripting here, is a really powerful feature.  Scripts can be either Groovy or JavaScript based, with a default Groovy script coming with OpenAM 13 out of the box.

The script is basically allowing us to creatively map scopes into attribute data, either held on the user's identity profile, or perhaps dynamically created at run time via call outs or via applied logic.

A quick edit of the of the out of the box OIDC claims script, allows me to add a users status from their profile held in OpenDJ, into the data available to presented scopes.  I've used the inetuserstatus attribute simply as it's populated by design.  By adding "status" to the scopes list on my OIDC client profile, allows it to be called and then mapped via the script.
So pretty simply I can add in what is made available from the user's identity profile, which could include permissions attributes or group data for example.

Another neat feature (which isn't necessarily part of the OIDC spec), is the ability to add claims data directly into the id_token - instead of making the extra hop to the user_info endpoint with the returned access_token.  This is useful for scenarios where "offline" token introspection is needed, where an application, API, device or service, wants to perform local authorization decision making, by simply using the information provided in the id_token.  This could be quite common in the IoT world.

To add the claims data into the signed JWT id_token, you need to edit the global OIDC provider settings (Configuration | Global | OAuth2 Provider).  Under this tab, use the check box "Always return claims in ID Tokens"



Now, when I perform a standard request to the ../access_token endpoint, including my openid scope along with my scripted scope, I receive an id_token and access_token combination the same as normal.



So I can either call the ../user_info endpoint directly, with my access_token to check my scope values (including my newly added status one) or use a tool or piece of code to introspect my id_token.  The JWT.io website is a quite a cool tool to introspect the id_token by doing the decode and signing verification automatically online.  The resulting id_token introspect would look something like this:


Note the newly added "status" attribute is in the verified id_token.

7 comments:

  1. Great scripts and solutions. For crm management visit us from the links below

    The dealer crm is something that will give any kind of business the basic need fulfilled without investing much of the mount. Another important thing with web based crm software is that it will help the task of managing the business with ease, web based crm software will prove as the best option. The option and features of this tool is perfect for use.

    ReplyDelete
  2. Hi Simon,
    I find it very usefull article and feature itself making whole system easy to configure. You have mentioned that maybe we can expose group data – could you provide example for that? I am still new to OpenAM and I am not able to locate name of attribute where I will get that information from.

    Thanks in advance for your help
    Robert

    ReplyDelete
  3. Hi Robert. Edit your script to add in something like ""groups" : attributeRetriever.curry("isMemberOf")" under the claimAttributes objects. Also add in "groups" : [ "groups"]" in the scopeClaimsMap. Make sure you also edit your datastore configuration to make isMemberOf available (Datastores, LDAP User Attributes...) to that AM instance. All that is hot swappable and is available soon as you click save. HTH

    ReplyDelete
  4. Hey,
    Thanks for sharing such an amazing and informative post. Really enjoyed reading it. :)

    Apu

    Medical Case Management Services

    ReplyDelete
  5. Hi Simon !

    Thanks for the helpful article !
    I've got an additional question though : you're saying we can map scopes into attribute data dynamically created at run time, would that include parameters included in the original HTTP request on the /oauth2/authorize endpoint ?
    If so, could you provide an example of the way we could implement that in the script ?

    Thanks again !

    ReplyDelete
  6. Does the following link explain - https://backstage.forgerock.com/docs/am/5/oidc1-guide#scripted-api-oidc-request

    ReplyDelete
  7. Hey,
    Thanks for sharing such an amazing and informative post. Really enjoyed reading it :)

    Thanks

    Apu

    Claims Management Services

    ReplyDelete