WSO2 apim get user roles in the backend

Viewed 113

I have an instance of WSO2 apim 4.1.0 with IS 5.11.0 using docker compose, I need to get the roles of the logged in user when sending requests through the backend of an application exposed via OpenApi with the WSO2 gateway.

I tried to add the role as mandatory claim as shown in this question but the token still does not contain the user roles.

Example token:

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik4ySmpNak5pTTJFeFlqUmtOelpqWm1ZMVlUQXhObUZsTmpnNE9XVTFZV1EyWXpjMU5tWTVOUT09In0=.eyJzdWIiOiJ0ZXN0VGVyYXBldXRhIiwiaHR0cDpcL1wvd3NvMi5vcmdcL2NsYWltc1wvYXBpbmFtZSI6Ik1hcHNFSCIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL2FwcGxpY2F0aW9udGllciI6IlVubGltaXRlZCIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL3ZlcnNpb24iOiIxLjAuMCIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL2tleXR5cGUiOiJQUk9EVUNUSU9OIiwiaXNzIjoid3NvMi5vcmdcL3Byb2R1Y3RzXC9hbSIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL2FwcGxpY2F0aW9ubmFtZSI6IkRlZmF1bHRBcHBsaWNhdGlvbiIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL2VuZHVzZXIiOiJ0ZXN0VGVyYXBldXRhQGNhcmJvbi5zdXBlciIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL2VuZHVzZXJUZW5hbnRJZCI6Ii0xMjM0IiwiaHR0cDpcL1wvd3NvMi5vcmdcL2NsYWltc1wvYXBwbGljYXRpb25VVUlkIjoiYTA4MzFjYjYtMzdlYy00ZWE2LTg4OTQtYzliNWZiMzViMmMwIiwiaHR0cDpcL1wvd3NvMi5vcmdcL2NsYWltc1wvc3Vic2NyaWJlciI6InRlc3RUZXJhcGV1dGEiLCJhenAiOiJOOEFWTzNRVzBkdllMVktzUWhUeV93dWQ3andhIiwiaHR0cDpcL1wvd3NvMi5vcmdcL2NsYWltc1wvdGllciI6IlVubGltaXRlZCIsInNjb3BlIjoiZGVmYXVsdCIsImV4cCI6MTY2MjExMDUzNywiaHR0cDpcL1wvd3NvMi5vcmdcL2NsYWltc1wvYXBwbGljYXRpb25pZCI6IjEiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC91c2VydHlwZSI6IkFwcGxpY2F0aW9uX1VzZXIiLCJpYXQiOjE2NjIxMDk2MzcsImp0aSI6ImFiMGVmMzU0LWZjZTMtNDIzMy04MzIzLTNlODQ0MWM1YzAwYiIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL2FwaWNvbnRleHQiOiJcL21hcHMtZWhcLzEuMC4wIn0=.iFVbpj3TG4UdtU3DhaLnMRGoIwfyHhenuCRr7C2t37lOlqJOsdLCeo0tGb_U5EsmdnHrN8kSscCG41v7JcOm97W5v7PKHtg95y3QKOTouzFppEq71DIXPmW51wDWh5EHNPFwXZ0e_371ZjXAOSB5UzStyzha7heg_DoPDTf1b6aLSP-9t50qsI4wT_HR7fm_Hmn-ZRL8ncmiuiQbofoGuTUHCmM1CfjiqQ_U65SAXgIKB2hATWaJFxqfr6emUsHMTdqS0_79DwxqHE_PdTQobBECOiU8RHZ_kxsQ1WpY__Ud9PEn13qRtGGV_Rp1LRd14iYF4l9ns1ENhNc1Tz0JNg==

Which translates to

{
  "sub": "testTerapeuta",
  "http://wso2.org/claims/apiname": "MapsEH",
  "http://wso2.org/claims/applicationtier": "Unlimited",
  "http://wso2.org/claims/version": "1.0.0",
  "http://wso2.org/claims/keytype": "PRODUCTION",
  "iss": "wso2.org/products/am",
  "http://wso2.org/claims/applicationname": "DefaultApplication",
  "http://wso2.org/claims/enduser": "testTerapeuta@carbon.super",
  "http://wso2.org/claims/enduserTenantId": "-1234",
  "http://wso2.org/claims/applicationUUId": "a0831cb6-37ec-4ea6-8894-c9b5fb35b2c0",
  "http://wso2.org/claims/subscriber": "testTerapeuta",
  "azp": "N8AVO3QW0dvYLVKsQhTy_wud7jwa",
  "http://wso2.org/claims/tier": "Unlimited",
  "scope": "default",
  "exp": 1662110537,
  "http://wso2.org/claims/applicationid": "1",
  "http://wso2.org/claims/usertype": "Application_User",
  "iat": 1662109637,
  "jti": "ab0ef354-fce3-4233-8323-3e8441c5c00b",
  "http://wso2.org/claims/apicontext": "/maps-eh/1.0.0"
}

I also tried to compile a custom token generator as shown in the official docs but the result is the same, here is the java code that I compiled into a jar with maven install, filename src/main/java/org/wso2/carbon/test/CustomTokenGenerator.java with the jar put in the path <API-M_HOME>/repository/components/lib.

import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext;
import org.wso2.carbon.apimgt.keymgt.token.JWTGenerator;

import java.util.HashMap;
import java.util.Map;

public class CustomTokenGenerator extends JWTGenerator {

    public Map<String, String> populateStandardClaims(TokenValidationContext validationContext)
            throws APIManagementException {
        Map<String, String> claims = super.populateStandardClaims(validationContext);
        boolean isApplicationToken =
                validationContext.getValidationInfoDTO().getUserType().equalsIgnoreCase(APIConstants.ACCESS_TOKEN_USER_TYPE_APPLICATION) ? true : false;
        String dialect = getDialectURI();
        if (claims.get(dialect + "/enduser") != null) {
            if (isApplicationToken) {
                claims.put(dialect + "/enduser", "null");
                claims.put(dialect + "/enduserTenantId", "null");
            } else {
                String enduser = claims.get(dialect + "/enduser");
                if (enduser.endsWith("@carbon.super")) {
                    enduser = enduser.replace("@carbon.super", "");
                    claims.put(dialect + "/enduser", enduser);
                }
            }
            claims.put(dialect + "/role", "null");
        }

        return claims;

    }

    public Map<String, String> populateCustomClaims(TokenValidationContext validationContext) throws APIManagementException{
        Long time = System.currentTimeMillis();
        Map<String,String> customClaims = new HashMap<String, String>();
        customClaims.put("current_timestamp", time.toString());
        customClaims.put(getDialectURI() + "/scope", validationContext.getValidationInfoDTO().getScopes().toString());
        return customClaims;
    }
}

And also here is my docker-compose file

version: '3'

services:
  mysql:
    image: mysql:5.7.37
    ports:
      - 3306
    environment:
      MYSQL_ROOT_PASSWORD: *
    volumes:
      - ./conf/mysql/scripts:/docker-entrypoint-initdb.d
      - ./conf/mysql/conf/my.cnf:/etc/mysql/my.cnf
    ulimits:
      nofile:
        soft: 20000
        hard: 40000
    command: [--ssl=0]
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-uroot", "-proot"]
      interval: 30s
      timeout: 60s
      retries: 5
      start_period: 80s
  is-as-km:
    build: ./dockerfiles/is-as-km (image wso2/wso2is:5.11.0)
    healthcheck:
      test: ["CMD", "nc", "-z","localhost", "9444"]
      interval: 10s
      start_period: 180s
      retries: 20
    depends_on:
      mysql:
        condition: service_healthy
    volumes:
      - ./conf/is-as-km:/home/wso2carbon/wso2-config-volume
    ports:
      - "9444:9444"
  api-manager:
    build: ./dockerfiles/apim (image wso2/wso2am:4.1.0)
    healthcheck:
      test: ["CMD", "nc", "-z","localhost", "9443"]
      interval: 10s
      start_period: 180s
      retries: 20
    depends_on:
      mysql:
        condition: service_healthy
      is-as-km:
        condition: service_healthy
    volumes:
      - ./conf/apim:/home/wso2carbon/wso2-config-volume
    ports:
      - "9443:9443"
      - "8280:8280"
      - "8243:8243"
  backend:
    build: .
    restart: always
    container_name: myapp
    #working_dir: /app
    ports:
      - "3000:3000"
      - "2999:3001"
    env_file:
      - .env
    volumes:
      - ./src:/home/node/app/src
      - ./public:/home/node/app/public
      - ./node_modules:/home/node/app/node_modules

Finally the relevant part of my deployment.toml file following

[apim.jwt]
enable = true
encoding = "base64" #base64,base64url
#generator_impl = "org.wso2.carbon.test.CustomTokenGenerator"
generator_impl = "org.wso2.carbon.apimgt.gateway.handlers.security.jwt.generator.APIMgtGatewayJWTGeneratorImpl"
claim_dialect = "http://wso2.org/claims"
#convert_dialect = false
header = "X-JWT-Assertion"
signing_algorithm = "SHA256withRSA"
enable_user_claims = true
claims_extractor_impl = "org.wso2.carbon.apimgt.impl.token.ExtendedDefaultClaimsRetriever"

#[apim.jwt.gateway_generator]
#impl = "org.wso2.carbon.test.CustomTokenGenerator"

[apim.key_manager]
service_url = "https://is-as-km:9444/services/"
type = "WSO2-IS"

Any hint about what may be wrong? Thanks

0 Answers
Related