1
votes

I'm developing some SpringBoot microservices that exposes REST through WSO2 APIM.

Microservice itself does not implement any kind of authentication or authorization mecanism, it is delegated to APIM.

If I set API to use Password Grant as described here, front end application can authenticate and generate JWT token.

The problem now is that I can't fetch user roles from JWT payload because it is not being added by APIM. This information is important because front-end render menus and buttons based on user roles.

The user I'm passing when generate token does have some roles as you can see bellow:

enter image description here

But generated JWT token does not include any information about roles. Here is a sample token:

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5UZG1aak00WkRrM05qWTBZemM1TW1abU9EZ3dNVEUzTVdZd05ERTVNV1JsWkRnNE56YzRaQT09In0.eyJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9hcHBsaWNhdGlvbnRpZXIiOiJVbmxpbWl0ZWQiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC92ZXJzaW9uIjoidjEiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9rZXl0eXBlIjoiUFJPRFVDVElPTiIsImlzcyI6IndzbzIub3JnXC9wcm9kdWN0c1wvYW0iLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9hcHBsaWNhdGlvbm5hbWUiOiJDYWRhc3RybyBkZSBDbGllbnRlcyIsImtleXR5cGUiOiJTQU5EQk9YIiwiaHR0cDpcL1wvd3NvMi5vcmdcL2NsYWltc1wvZW5kdXNlciI6ImVtaWxpb0BjYXJib24uc3VwZXIiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9lbmR1c2VyVGVuYW50SWQiOiItMTIzNCIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL3N1YnNjcmliZXIiOiJhZG1pbiIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL3RpZXIiOiJVbmxpbWl0ZWQiLCJzY29wZSI6ImRlZmF1bHQiLCJleHAiOiIxNTk5NTYyOTQ4MDI4IiwiaHR0cDpcL1wvd3NvMi5vcmdcL2NsYWltc1wvYXBwbGljYXRpb25pZCI6IjIiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC91c2VydHlwZSI6IkFwcGxpY2F0aW9uX1VzZXIiLCJjb25zdW1lcktleSI6IktJaTdnUk1RYmg1OWZGbmpVOFhNbnhGcm9pNGEiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9hcGljb250ZXh0IjoiXC9ia25nXC92MSJ9.km4w2V7dGmoGl8f4_ZqKHvdofAPLOOw__GPjWKrpjYelbi7IjDIpRODEZNn8hE1krRdDTSjKRviJ-NBvXtTXIiLdfPh1p-zNtX26vrS77ZcSZ2WsQA7Ku21YMqcm6cyZvEhZ99qfTxOtbJfkwt6Yt8itkyr-aqk83pNp85LTnwtNboib9VOOvh37zNEJUImzKw4WvENp4SGLuHO978FriHyHPN9vibzPjpItW5DOXTFNdN4rP6RK_vcOH6hpuZHwivJpTHxf9qMB3Gd2yTig-Hkr-sZGbx89pQf8kqtCLWbhRG5jOtcEJNf2CSNLB0Glg_e4F6LfhVD5JUCz15jdlg

When I extract it in https://jwt.io/ I get following payload:

{
  "http://wso2.org/claims/applicationtier": "Unlimited",
  "http://wso2.org/claims/version": "v1",
  "http://wso2.org/claims/keytype": "PRODUCTION",
  "iss": "wso2.org/products/am",
  "http://wso2.org/claims/applicationname": "Cadastro de Clientes",
  "keytype": "SANDBOX",
  "http://wso2.org/claims/enduser": "[email protected]",
  "http://wso2.org/claims/enduserTenantId": "-1234",
  "http://wso2.org/claims/subscriber": "admin",
  "http://wso2.org/claims/tier": "Unlimited",
  "scope": "default",
  "exp": "1599562948028",
  "http://wso2.org/claims/applicationid": "2",
  "http://wso2.org/claims/usertype": "Application_User",
  "consumerKey": "KIi7gRMQbh59fFnjU8XMnxFroi4a",
  "http://wso2.org/claims/apicontext": "/bkng/v1"
}

How do I add user roles to JWT payload? Do I need to implement a custom generator as described here?

Thanks in advance!

1
In which token do you need role claim included? Is it the Authentication JWT or Backend JWT?Praminda
Actually I was expecting to pass APIM generated token to backend to check roles when necessary or get roles in front-end to render specific content based on roles. Is this a viable approach? If so, is it a good practice?Emilio Numazaki
Did you try ClaimsRetrieverImplClass configuration. Usage is documented in the "Passing enduser attributes..." doc.Praminda
Yes it works but it is valid only for JWT sent to backend, I mean, APIM gets the request, checks JWT sent over header, generate new JWT and forwards to backend. This class and article is for this purpose no to client JWT, isn't it? What I need is user roles to JWT generated to API client.Emilio Numazaki
Can you confirm the apim version in use?Praminda

1 Answers

2
votes

Easiest way to get role claim included in the auth JWT is to add a claim mapping in service provider level and request the token with openid scopes. To do this try below steps.

  1. Log in to management console https://<host>:<port>/carbon

  2. List service providers in the left menu

  3. Go to edit on the required service provider (Each application in the developer portal has a mapping service provider)

  4. Add a claim mapping to role claim as below enter image description here

  5. Send the token request with the scope=openid parameter

    curl -k -X POST https://localhost:8243/token -d "grant_type=password&username=<Username>&password=<Password>&scope=openid" -H "Authorization: Basic <Credentials>"
    
  6. Response access token will contain roles in this format

    {
        "sub": "[email protected]",
        "iss": "https://localhost:9443/oauth2/token",
        "groups": [
            "Internal/subscriber",
            "Internal/creator",
            "Application/apim_devportal",
            "Application/admin_NewApp_PRODUCTION",
            "Internal/publisher",
            "Internal/everyone",
            "Internal/analytics",
        ],
        ...
    }