'Namespace' for custom claims

Hi

I have an Authorization Server which is happily returning various ‘out of the box’ and custom claims as necessary which is great.

The back-end (DGraph GraphQL hosted server https://slash.dgraph.io/) requires a ‘namespace’ for the claims I want it to use but all of the claims in my token are at the root of the payload.

My example JWT from Okta is:

{
  "sub": "xxxxxxxxxxxxxxxxxxx",
  "ver": 1,
  "iss": "https://abc-1234567.okta.com/oauth2/default",
  "aud": "xxxxxxxxxxxxxxxxxxx",
  "iat": 1609590699,
  "exp": 1609594299,
  "jti": "ID.xxxxxxxxxxxxxxxxxxx",
  "amr": [
    "pwd"
  ],
  "idp": "xxxxxxxxxxxxxxxxxxx",
  "nonce": "nonce",
  "auth_time": 1000,
  "CustomClaim1": "xxxxxxxxxxxxxxxxxxx",
  "CustomClaim2": "xxxxxxxxxxxxxxxxxxx"
}

What DGraph wants is…

{
  "sub": "xxxxxxxxxxxxxxxxxxx",
  "ver": 1,
  "iss": "https://abc-1234567.okta.com/oauth2/default",
  "aud": "xxxxxxxxxxxxxxxxxxx",
  "iat": 1609590699,
  "exp": 1609594299,
  "jti": "ID.xxxxxxxxxxxxxxxxxxx",
  "amr": [
    "pwd"
  ],
  "idp": "xxxxxxxxxxxxxxxxxxx",
  "nonce": "nonce",
  "auth_time": 1000,
  "Namespace": {
     "CustomClaim1": "xxxxxxxxxxxxxxxxxxx",
     "CustomClaim2": "xxxxxxxxxxxxxxxxxxx"
  }
}

I just noticed whilst writing this that the address scope creates an output where there is effectively a namespace with claims which is what I’m after

"address": {
    "street_address": "My House",
    "locality": "My Town",
    "region": "My County",
    "postal_code": "My Postcode"
  }"

How does one achieve that?!?!

Hello,
You can try the following

  1. directory->profile editor->(find your application and click profile)

  2. click ‘add attribute’

  • data type=string array

  • give variable name (ie app_perm) and display name

  • Group Priority = combine

  1. applications->(your app)->assignments->(filters groups)

  2. click the edit button on a group you have assigned the app

  3. for the attribute just created (ie app_perm) click ‘add another’ for every claim you want to show up in your claims (‘Create’, ‘Read’, ‘Delete’)

  4. In your authorization server click scopes and add a scope name/display/description (ie app:perms)

  5. Click Claims and add a claim

  • token type (access or id)

  • Value Type = Expression

  • Value = (appuser.${the name of your attribute from step 2} (ie appuser.app_perm)

  • the following scope = the scope just created (app:perms)

  1. Click token preview
  • OAuth/OIDC client = your app

  • choose the grant type for your app and a user assigned the app

  • scopes (openid and the custom scope created)

Click preview token and select the token your claim is mapped to

{
  "ver": 1,
  "jti": "AT.5XoRE2G6oNSxiuqcqUr3SObdn-8pGbkt-EGCdZmBDLQ",
  "iss": "https://some.domain.com/oauth2/aus5qj9tdEkuA12S71d6",
  "aud": "http://localhost:5000",
  "iat": 1609790883,
  "exp": 1609794483,
  "cid": "0oa5i563mykj6ch0U1d6",
  "uid": "00u4w1vmhtTY8Ciuw1d6",
  "scp": [
      "app:perms",
      "openid"
  ],
  "sub": "igor.dean@oktaice.com",
  "app_perms": [
      "Create",
      "Read",
      "Delete"
  ]
}

Thanks @erik

I am not looking to generate a string array of values rather effectively a nested subset of claims.

Using an address as an example… The detail provided to create a string array may allow me to produce:

"address":[
    "Building",
    "Street",
    "City",
    "Postcode"
]

However this claim “address” is still at the root of the payload with the values in it being “Building”, “Street”, “City” etc…

However what I am needing to achieve is a nested subset of claims - effectively what you already create for the built in address scope:

"address": {
    "street_address": "Building",
    "locality": "Street",
    "region": "City",
    "postal_code": "Postcode"
  }"

In this instance address is a ‘namespace’ at the root of the payload which has no value itself but contains a series of nested claims where the nested claim “street_address” has a value of “Building”, the nested claim “locality” has a value of “Street” etc…

Given the address claim implements this functionality it must be possible for Okta to do this; I am just unsure if it is exposed as something one can implement?

Is it possible to describe how one would implement the same functionality as the default address scope has as that would meet my requirements?

One way to do it would be with a token hook.
If the hook was to return

 return { 
         "commands": [
             {
                 // modified access token
                 "type": "com.okta.access.patch",
                 "value": [
                     {
                     "op": "add",
                     "path": "/claims/myClaim",
                     "value": {
                         "claim1": "val1",
                         "claim2": "val2"
                         }
                     }
                 ]
             }
        ]
    }

the access token would be modified to contain myClaim object,

 "sub": "0oa8rc1vvUWbpGroC1d6",
 "myClaim": {
  "claim1": "val1",
  "claim2": "val2"
 }
1 Like

Hi @erik

The method you suggest seems to generate the output format I am looking for - essentially a section of JSON

 "myClaim": {
      "claim1": "val1",
      "claim2": "val2"
 }

I’ve had a look to set it up but it seems that the inline token hook is intending to get the additional claims from another service hosted elsewhere as per 2 from the below list of settings. The settings to in the set-up are:

  1. Name : a descriptive name for the Inline Hook
  2. URL : the external service’s endpoint URL, to which the Inline Hook sends the request
  3. Authentication field : the name of the authorization header
  4. Authentication secret : the value string that corresponds to the field name
  5. Custom header fields : optional field name / value pairs to send with the request

The claims I want to add in the above example are things like the user email, name, unique id etc from their Okta profile not third party data from elsewhere. Say something like…

  "profile": {
    "firstName": "Isaac",
    "lastName": "Brock",
    "email": "isaac.brock@example.com",
    "login": "isaac.brock@example.com",
    "mobilePhone": "555-415-1337"
  }

Have I misunderstood this inline hook method?

With a token hook you can add/update/remove claims. So potentially you should be able to send all the claims you need at the root level, have the hook create a new object with child claims using those values, and then remove the root level claims. Note there are some claims you can’t remove/modify and there are some reserved key words.

Hi there!

Erin here from the Okta Dev Support team. I had a chance to discuss this with @the_biochemist and it looks like we were able to solve the issue without using token hooks (suggested above).

  1. Log in to your Okta admin dashboard
  2. Go to Security -> API
  3. Click on the name of the Authorization Server you’re using
  4. Click the Claims tab
  5. Click Add claim
  6. In the value field, include the claim information as an object using Okta’s expression language.
    Here is an example:

After you’ve set this up, if you click the “Token Preview” tab, you can enter in your information and see an example of what the token will look like.

@erin.p

Thanks for your help on this… Surprisingly easy when you know how!!!

I would mention though… I have spent a long time looking through your documentation and have noticed that it tells you ‘what the various bits of the system do’ in immense detail but really lacks an explanation of ‘how you use it to do something’ if that makes sense.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.