Push claims

After a user has been authenticated, websites often find it useful to retrieve information from the user’s user profile; this information can then be used to do things like, say, personalize the user experience. Recognizing the importance of this, OAuth provides two methods scopes and claims for retrieving user information and then storing that data in the user’s identity token and/or making it readily-accessible from the userinfo endpoint.

As useful as scopes and claims can be, however, working with these items can also be a time-consuming (and an error-prone) procedure. For example, suppose you work for a large organization that has a large number of OIDC login clients and an equally large number of authorization request types. If you want to use the same scopes and claims in each request, you’ll need to make sure that each administrator who creates an authorization request uses the same set of scopes and claims.

Granted, that might not sound all that bad … at least not until you need to change those scopes and claims. At that point, and to maintain consistency, you’ll have to change all your authorization requests (and, depending on the changes, have to change all your login and token policies as well). Like we said, that can be a tedious and time-consuming process.

At best.

On top of that, the claims parameter requires JSON formatting, a fact that often poses challenges to administrators creating authorization requests. For example, the following snippet adds two custom claims (organization and cellPhone) to the identity token and the userinfo endpoint:

&claims={"userinfo":{"organization":null,"cellPhone":null},"id_token":{"organization":null,"cellPhone":null}}

It’s no exaggeration to say that getting all those braces, quote marks, commas, and colons in the exact right place can be a … challenge ….

To help overcome these issues the Identity Cloud has introduced a new feature: push claims. By default (that is, without push claims), scopes and claims must be included in each authorization request: if you create five new requests you’ll have to add the scopes and claims parameters to each of those requests. With push claims, however, you simply add custom claims to your login policy, one claim for each piece of user information (first name, last name, middle initial, etc.) that you want returned following a successful authentication. From that point on, every authorization request that uses that login policy will automatically return all those claims, and without having to use the scopes parameter, the claims parameter, or any sort of special push claims parameter.

For example, suppose you do create five new authorization requests. Assuming those requests use the same login policy, then each request returns all of your custom claims. And, once again, without requiring any effort on your part.


📘

But what if you do this and then, for whatever reason, you include the scopes parameter or the claims parameter in your authorization request? That’s fine: as we’ll see in a moment, those parameters are ignored and only your custom claims will be pushed to you.


In this documentation, we’ll explain the push claim process in more detail, show you how to enable and disable the use of push claims, and demonstrate how to add custom claims to your login policy.


📘

You can find more information about adding custom claims to a login policy in our Scopes and Claims article. Because push claims are just custom claims, the process used to add them to a login policy is the same process used to add any custom claim to a login policy.


How push claims work

Push claims provide a way to standardize and centralize scopes and claims in your organization (and, as an added bonus, help relieve administrators from having to figure out how to add JSON-formatted claims into their authorization requests). Push claims, which override any scopes or claims included in an authorization request (except for the openid scope), work something like the following:

First, you must undertake a two-step process that adds push claims to a login policy and then enables the use of those push claims. This is done by:

  1. Adding a set of custom claims to a login policy. For example, this syntax adds three custom claims (referencing three custom user profile attributes: emailMarketingOptin, uiPreferencesOptin, and personalizedAdsOpti) to the identity token:
{
     "customClaims":
       {"id_token":
         {
           "consentEmailMarketing": "emailMarketingOptIn",
           "consentUiPreferences": "uiPreferencesOptIn",
           "consentPersonalizedAds": "personalizedAdsOptIn"
         }
       }
    }
    ```
  1. After all the claims have been added, use the /loginPolicies/{loginPolicyId}/pushClaims endpoint and the PUT method to set the value of the login policy’s pushClaims property to true. Here’s a Curl example that shows how this endpoint works:
curl -L -X PUT \
     'https://v1.api.us.janrain.com/e0a70b4f-1eef-4856-bcdb-f050fee66aae/config/loginPolicies/
   1e1ab726-f4b5-4bad-ba45-877027af4097/pushClaims' \
     -H 'Authorization: Bearer dgqJbjCmon__P9OXLz5ulJtpS-jupleB-MBejblVMZHS8Nc-EeMSl91_b76WhtdA' \
     -H 'Content-Type: application/json' \
     --data-raw 'true'

After the login policy has been configured, you’re ready to make your authorization request. Note that this authorization request doesn’t include any of the three custom claims (e.g., emailMarketingOptin) we just added to the login policy. In fact, the request doesn’t use the claims parameter at all (although, primarily for educational purposes, it does specify the email scope):

https://v1.api.us.janrain.com/e0a70b4f-1eef-4856-bcdb-f050fee66aae/login/authorize
    ?client_id=64430515-01ea-4f5d-82e4-c36161af0093
    &redirect_uri=https://oidc-playground.akamai.com/redirect_uri
    &scope=openid email
    &code_challenge=3Ur2XqjKrRPo7854J3K-EIFxGjs3MBSKxfzH6CjT36c
    &code_challenge_method=S256
    &response_type=code
    &state=ev0kBLfyyH2re4XeMK22ftcKwFNqCq4D7dwfOhWQXMI

Here are the scopes and claims available from the userinfo endpoint and in the identity token following a successful authentication:

Userinfo EndpointIdentity Token
 emailMarketingOptin
uiPreferencesOptin
personalizedAdsOptin

As you can see, the identity token includes three claims; it’s no coincidence that these are the three custom claims defined in the login policy. And yes, these claims appear only in the identity token; that’s because, when adding the claims to the login policy, we only asked that they be made available in the identity token.

And what about the email scope? Well, because push claims have been enabled, scopes (other than the required openid scope) are ignored. That means that the email scope is ignored; in turn, that means that the email scope isn’t available from the userinfo endpoint.

That’s how push claims work: following a successful authentication, all the custom claims in the login policy are pushed out to the client even if those custom claims aren’t included in the authorization request. Meanwhile, any scopes or standard claims that are included in the authorization request are ignored. If push claims have been enabled, the following scenario plays out each time an authorization request is submitted:

  1. The scope and claims parameters are removed from the request (again, with the exception of the openid scope). For all intents and purposes, you’re now submitting an authorization request that doesn’t ask for any scopes or claims.

  2. Following a successful authentication, Hosted Login retrieves the custom claims defined in the login policy and, as appropriate, makes that information available from the userinfo endpoint or adds it to the identity token.

Here’s another quick example, just to reiterate the point. Suppose we have push claims enabled, and we have the following claims defined in the login policy:

{
"customClaims": {
      "id_token": {
           "userEmailAddress": "email",
           "userEmailAddressVerified": "emailVerified"
      },
      "userinfo": {
           "userEmailAddress": "email",
           "userEmailAddressVerified": "emailVerified"
      }
    }
}

As you can see, we’re defining two custom claims – userEmailAddress (which is associated with the email user profile attribute) and userEmailAddressVerified (associated with the emailVerified attribute) – and adding these claims to the identity token and the userinfo endpoint.


📘

Good point: the email and emailVerified attributes are returned by the email scope, aren’t they? So then why don’t we just request the email scope in our authorization request and be done with it? You’re way ahead of us: because we’ve enabled push claims the email scope (along with any other scopes and claims) are ignored when the user logs on. If we want to get back information found in the email scope we need to define custom claims that return that information. Anything you want to be accessible from the userinfo endpoint or want to add to the identity token must be defined as a custom claim. No exceptions.


With our new custom claims defined, let’s make another authorization request. This time, our userinfo endpoint and identity token look like this:

Userinfo EndpointIdentity Token
userEmailAddress userEmailAddressVerifieduserEmailAddress userEmailAddressVerified

Again, the information dispersed to the userinfo endpoint or added to the identity token happens to be the custom claims defined in the login policy. That’s how push claims work.


Manage push claims

To this point we’ve talked about enabling push claims in a login policy, and we’ve talked about defining custom claims. What we haven’t discussed, however, is push claims management. For example, how do you know whether push claims have been enabled in a login policy? Well, because push claims are a login policy property, the obvious answer would seem to be this: you use the /loginPolicy/{loginPolicyId} endpoint to return the properties and property values of your login policy. That makes sense, but notice what happens when you do return the properties and property values of a login policy:

{
    "id": "1e1ab726-f4b5-4bad-ba45-877027af4097",
    "identityStoreDetails": {
        "type": "janrainCapture",
        "connectionDetails": {
            "domain": "us-dev.janraincapture.com",
            "applicationId": "ces7u7uwwudrxtz933jvbehzne",
            "entityType": "user",
            "clientId": "6s7q89env535ek49hkz6hjsh3jgs93ud",
            "clientSecret": "7b7eqyuswtnpaa6zxdvuafum56r4cbsw"
        }
    },
    "loginURL": "https://v1.api.us.janrain.com/e0a70b4f-1eef-4856-bcdb-f050fee66aae/auth-ui/login",
    "title": "Dev Login Policy",
    "_links": {
        "self": {
            "href": "/config/e0a70b4f-1eef-4856-bcdb-f050fee66aae/loginPolicies/1e1ab726-f4b5-4bad-ba45-877027af4097"
        }
    }
}

As you can see, there’s no pushClaims property to be found, even though we just enabled push claims just a few minutes ago. Did we do something wrong?

As it turns out, no, we didn’t do anything wrong. Instead, push claims have their very own API endpoint: /loginPolicies/{loginPolicyId}/pushClaims. To return the status of push claims for a given login policy, you use this endpoint and the GET method. For example:

curl -L -X GET \
  'https://v1.api.us.janrain.com/e0a70b4f-1eef-4856-bcdb-f050fee66aae/config/loginPolicies/1e1ab726-f4b5-4bad-ba45-877027af4097/pushClaims' \
  -H 'Authorization: Bearer 1_Cs5nsYnMlDFE0usYiPU7NlrH_81CjiOqzrDKeuvSQumxAPrbwzQE18V9OQIbMr'

That returns a Boolean value that tells us whether or not push claims have been enabled. In this case, they have:

true

You use this same endpoint (and the PUT method) if you want to disable push claims in a login policy. That’s something this Curl command does:

curl -L -X PUT \
  'https://v1.api.us.janrain.com/e0a70b4f-1eef-4856-bcdb-f050fee66aae/config/loginPolicies/1e1ab726-f4b5-4bad-ba45-877027af4097/pushClaims' \
  -H 'Authorization: Bearer dgqJbjCmon__P9OXLz5ulJtpS-jupleB-MBejblVMZHS8Nc-EeMSl91_b76WhtdA' \
  -H 'Content-Type: application/json' \
  --data-raw 'false'

Incidentally, you can toggle between push claims being enabled and push claims being disabled as often as you want. Just remember that each time you switch from one mode to the other any scopes or claims included in your authorization request will also either be enabled or disabled. If push claims are enabled, then the scope and claims parameters are, for all intents and purposes, disabled. If push claims are disabled, then the scope and claims parameters are enabled. In other words:

If push claims are …Then the scope and claim parameters …
Enabled… are ignored, and only claims defined in the login policy are used to add user information to the identity token and the userinfo endpoint.
Disabled… are used to add user information to the identity token and the userinfo endpoint