Passing End User Attributes to the Backend

There can be scenarios where a backend service needs to make different decisions or respond with different data, depending on the application end-user that consumes an API. To achieve this the backend service needs to have access to the respective end-user's data at the time an API call takes place.

This can be facilitated by the Gateway by sending the end user attributes that are defined in the respective user store, in a JWT via an HTTP header, to the backend service when the API call is being forwarded.

How does it work?

The backend JSON Web Token (JWT) contains the claims that are transferred between two parties, such as the end-user and the backend. A claim is an attribute of the user that is mapped to the underlying user store. A set of claims is referred to as a dialect (e.g., http://wso2.org/claims).

If you enable backend JWT generation in the Gateway, each API request will carry a digitally signed JWT, which is in the following format to the backend service.

{token header}.{claims list}.{signature}

When the request goes through the Gateway, the backend JWT is appended as a transport header to the outgoing message. The backend service fetches the JWT and retrieves the required information about the user, application, or token.

Sample JWT

The following is an example of a JWT:

{
    "typ":"JWT",
    "alg":"NONE"
    }{
    "iss":"wso2.org/products/am",
    "exp":1345183492181,
    "http://wso2.org/claims/subscriber":"admin",
    "http://wso2.org/claims/applicationname":"app2",
    "http://wso2.org/claims/apicontext":"/placeFinder",
    "http://wso2.org/claims/version":"1.0.0",
    "http://wso2.org/claims/tier":"Silver",
    "http://wso2.org/claims/enduser":"sumedha"
    }

The above JSON Web Token (JWT) contains the following information.

JWT Header : The header section declares that the encoded object is a JWT access token and the JWT is in plain text, that is not signed using any encryption algorithm.

JWT Claims set :

  • "iss" - The issuer of the JWT
  • "exp" - The token expiration time
  • "http://wso2.org/claims/subscriber" - Subscriber to the API, usually the app developer
  • " http://wso2.org/claims/applicationname" - Application through which API invocation is done
  • " http://wso2.org/claims/apicontext" - Context of the API
  • " http://wso2.org/claims/version " - API version
  • " http://wso2.org/claims/tier" - Tier/price band for the subscription
  • " http://wso2.org/claims/enduser" - End-user of the app who's action invoked the AP

Enabling the default backend JWT generator

Before passing end user attributes, you need to enable and configure the JWT implementation, as mentioned below in Choreo Connect.

  1. Open the Choreo Connect configuration file according to the deployment type you are using.

    Click here to see the configuration file location for your Choreo Connect deployment.

    Navigate to the correct folder path and open the config.toml or config-toml-configmap.yaml file based on your Choreo Connect deployment.

    Deployment Mode File name Directory
    Docker Compose Choreo Connect as a Standalone Gateway config.toml <CHOREO-CONNECT_HOME>/docker-compose/choreo-connect/conf/
    Docker Compose Choreo Connect with WSO2 API Manager as a Control Plane config.toml <CHOREO-CONNECT_HOME>/docker-compose/choreo-connect-with-apim/conf/
    Kubernetes Choreo Connect as a Standalone Gateway config-toml-configmap.yaml <CHOREO-CONNECT_HOME>/k8s-artifacts/choreo-connect/
    Kubernetes Choreo Connect with WSO2 API Manager as a Control Plane config-toml-configmap.yaml <CHOREO-CONNECT_HOME>/k8s-artifacts/choreo-connect-with-apim/
  2. Enable and configure the backend JWT implementation.

    The following is the basic configuration that you need to have in place to enable backend JWT. For more information, on the other backend JWT configurations, see JWT generation configuration details.

    [enforcer.jwtGenerator]
        enabled = true
  3. Start the server.

    For more information, see the Quick Start Guide.

Enabling a customized backend JWT generator

Note

WSO2 API Manager comes with the default JWT generator. This JWT generator will generate specific claims based on the specifications and the user demands at the time the product is released. When you update the products, you will need to add/change some of the claims based on the specification updates. This means that even with the given released version, standard claims that come from the API Manager are subjected to change. Therefore, if you have planned to use specific claims in the backend, it is always recommended to implement a custom JWT generator with mandatory claims you wish to consume at your backend

When generating the backend JWT, it retrieves the claims from the invoked JWT. If you need to change the way that JWT is generated in Choreo Connect, such as by adding additional claims or by completely changing the JWT, follow the instructions below to implement the customized Gateway JWT generation:

  1. Write your own JWTGenerator class extending the org.wso2.carbon.apimgt.common.gateway.jwtgenerator.AbstractAPIMgtGatewayJWTGenerator class.

    Info

    Choreo Connect uses the AbstractAPIMgtGatewayJWTGenerator class to support JWT generation within Choreo Connect.

        package org.wso2.carbon.test;
    
    import org.osgi.service.component.annotations.Component;
    import org.wso2.carbon.apimgt.common.gateway.dto.JWTInfoDto;
    import org.wso2.carbon.apimgt.common.gateway.jwtgenerator.APIMgtGatewayJWTGeneratorImpl;
    import org.wso2.carbon.apimgt.common.gateway.jwtgenerator.AbstractAPIMgtGatewayJWTGenerator;
    
    import java.util.Map;
    import java.util.UUID;
    
    @Component(
            enabled = true,
            service = AbstractAPIMgtGatewayJWTGenerator.class,
            name = "customgatewayJWTGenerator"
    )
    public class CustomGatewayJWTGenerator extends APIMgtGatewayJWTGeneratorImpl {
    
        @Override
        public Map<String, Object> populateStandardClaims(JWTInfoDto jwtInfoDto) {
    
            return super.populateStandardClaims(jwtInfoDto);
        }
    
        @Override
        public Map<String, Object> populateCustomClaims(JWTInfoDto jwtInfoDto) {
    
            Map<String, Object> claims = super.populateCustomClaims(jwtInfoDto);
            claims.put("uuid", UUID.randomUUID().toString());
            return claims;
        }
    }

    Click here for a sample Custom Gateway JWTGenerator.

  2. Build your class and add the JAR file in the <MG_HOME>/resources/enforcer/dropins directory.

  3. Enable and configure the JWT implementation.

    • For more information, see JWT generation configuration details.

    • Set enforcer.jwtGenerator.gatewayGeneratorImpl to your customized class name.

      [enforcer.jwtGenerator]
      gatewayGeneratorImpl = "org.wso2.carbon.test.CustomGatewayJWTGenerator"
  4. Start the server.

    For more information, see the Quick Start Guide.

Backend JWT generator configuration details

The following is a sample configuration.

[enforcer.jwtGenerator]
    enabled = true
    encoding = "base64" # base64,base64url
    claimDialect = "http://wso2.org/claims"
    convertDialect = false
    header = "X-JWT-Assertion"
    signingAlgorithm = "SHA256withRSA"
    enableUserClaims = false
    gatewayGeneratorImpl = "org.wso2.carbon.test.CustomGatewayJWTGenerator"
    claimsExtractorImpl = "org.wso2.carbon.apimgt.impl.token.ExtendedDefaultClaimsRetriever"
    publicCertificatePath = "/home/wso2/security/truststore/mg.pem"
    privateKeyPath = "/home/wso2/security/keystore/mg.key"

The relevant elements in the JWT generation configuration are described below. If you do not configure these elements, they take their default values.

Element Description Default Value
enforcer.jwtGenerator.enable
Uncomment this property and set this value to true to enable JWT. false
enforcer.jwtGenerator.header
The name of the HTTP header to which the JWT is attached. X-JWT-Assertion
enforcer.jwtGenerator.claimDialect

The JWT access token contains all claims that are defined in the enforcer.jwtGenerator.claimDialect element. The default value of this element is http://wso2.org/claims. To get the list of a specific user's claims that need to be included in the JWT, uncomment this element after enabling the JWT. It will include all claims in http://wso2.org/claims to the JWT access token.

http://wso2.org/claims
enforcer.jwtGenerator.convertDialect
Remap the OIDC claims into the configured dialect false
enforcer.jwtGenerator.signingAlgorithm

The signing algorithm is used to sign the JWT. The general format of the JWT is {token header}.{claims list}.{signature}. When `NONE` is specified as the algorithm, signing is turned off and the JWT looks as {token header}.{claims list} with two strings delimited by a period and a period at the end.

This element can have only two values - the default values are SHA256withRSA or NONE.

SHA256withRSA
enforcer.jwtGenerator.enableUserClaims

Enable/disable user claims in the token

false
enforcer.jwtGenerator.gatewayGeneratorImpl

Fully qualified custom JWT generator to used in JWT(Self Contained) Access Tokens.

org.wso2.carbon.apimgt.common.gateway.jwtgenerator.APIMgtGatewayJWTGeneratorImpl
enforcer.jwtGenerator.claimsExtractorImpl

Fully qualified custom Claim Retriever to add custom claims into JWT.

org.wso2.carbon.apimgt.impl.token.ExtendedDefaultClaimsRetriever
enforcer.jwtGenerator.publicCertificatePath

Path of the public certificate

/home/wso2/security/truststore/mg.pem
enforcer.jwtGenerator.privateKeyPath

Path of the private key

/home/wso2/security/keystore/mg.key

See Also

If you want to learn how you can pass end user attributes to the backend when working with the default API Gateway, see Passing Enduser Attributes to the Backend, which is under the API Gateway documentation section.

Top