Building JSON Web Tokens in Liberty

You can programmatically build JSON Web Token (JWT) tokens by configuring the JWT builder element in the server configuration and implementing the com.ibm.websphere.security.jwt.JwtBuilder and com.ibm.websphere.security.jwt.JwtToken APIs in your applications.

About this task

For information about JWT APIs, see the JSON Web Token Java documentation or the API documentation included in the product in the ${wlp.install.dir}/dev directory.

Complete one of the following steps to build a JSON Web Token:

Procedure

  • Build a JSON Web Token without programming by using the token generation endpoint.
    1. In the server.xml file, add the jwt-1.0 feature.
    2. Use the default token generation endpoint at the https://<host>:<port>/jwt/ibm/api/defaultJWT/token URL.
      • This endpoint builds a token from the credentials that you provide.
      • If the credentials are already available to the endpoint, those credentials are used by default.
      • If you use a browser and navigate to this endpoint without credentials, the endpoint returns an authentication challenge to the browser.
      • The endpoint returns an MP-JWT format token in JSON form.
      • The token contains the userid and groups for the user as recorded in the user registry of the server.
    3. To configure additional options, such as issuer and expiration time, complete the following steps:
      1. Edit your server.xml file.
      2. Add a new jwtBuilder element that includes the available attributes that you want. For more information, see JWT Builder (jwtBuilder).
      3. Use the token generation endpoint at the https://<host>:<port>/jwt/ibm/api/(jwtBuilderId)/token URL.
  • Build a JSON Web Token programmatically.
    1. In the server.xml file, add the jwt-1.0 feature.
      <featureManager>
          <feature>jwt-1.0</feature>
          ...
      </featureManager>
    2. Configure the JWT builder by modifying the jwtBuilder element.

      For information about jwtBuilder attributes that you can configure, see JWT Builder (jwtBuilder).

      When you add the jwt-1.0 feature and save your changes, Liberty adds the following default jwtBuilder element.
      <jwtBuilder id="defaultJWT">
      </jwtBuilder>
      In this default configuration, the following values are assumed:
      • The exp claim is 2 hours after the token creation time. You can configure this value on the expiry attribute.
      • The iss claim is set to https://<host_name>:<ssl_port>/jwt/defaultJWT. Configure the issuer on the issuer attribute.
      • The JWT is signed by using the RS256 algorithm with a private key in the default keystore of the server. This configuration assumes that a default keystore is configured for the server, that the default keystore contains a single private key, and that the private key can be used for signing. If you specify a different keystore on the keyStoreRef attribute, the private key from the specified keystore is used. If the keyAlias attribute is not configured and the keystore contains only one private key, that private key is used in the signature.

      You can reconfigure this default jwtBuilder element, or create one or more other jwtBuilder elements. Each jwtBuilder element must have a unique, URL-safe string specified as the id attribute. If the ID is missing, the jwtBuilder is not processed.

      If the JWT token is signed by using the RS256 algorithm, you can configure the JWT builder to sign the JWT token with JSON Web Key (JWK) by setting jwkEnabled="true". When JWK is enabled, the JWT builder dynamically generates key pairs and signs the JWT token with the private key. To validate the signature, the JWT consumer can retrieve the key from the JWK API, which has the following format:
      https://<host_name>:<ssl_port>/jwt/ibm/api/<jwtBuilder_configuration_id>/jwk
    3. Programmatically build JWT tokens by implementing the com.ibm.websphere.security.jwt.JwtBuilder and com.ibm.websphere.security.jwt.JwtToken APIs in your application.

      For more information, see the JSON Web Token Java documentation.

      1. Create a JwtBuilder object.
        • If you do not specify a configuration ID, the object is tied to the default jwtBuilder configuration.
          com.ibm.websphere.security.jwt.JwtBuilder jwtBuilder = JwtBuilder.create();
        • If you specify a configuration ID, the object is tied to the jwtBuilder configuration with the specified ID.
          com.ibm.websphere.security.jwt.JwtBuilder jwtBuilder = JwtBuilder.create("jwtBuilder_configuration_id");
      2. Modify the claims in the token.
        • Add or update a claim: jwtBuilder.claim("claim_name", "claim_value");
          jwtBuilder.claim("role", "monitor");
        • Delete a claim: jwtBuilder.remove("claim_name");
          jwtBuilder.remove("role");
        • Fetch a claim from the Liberty Federated User Registry: jwtBuilder.fetch("attribute_name");

          This fetch call tells the JwtBuilder object to search the Federated User Registry for the user name identified by the sub claim of the JWT. The JwtBuilder object fetches the value of the specified attribute and creates a new claim based on that attribute. The name of the new claim is set to the attribute name, and the value of the new claim is set to the attribute value.

        • Copy a claim from an existing JWT or JSON object: jwtBuilder.claimFrom(JSON_or_JWT, "claim_name");
      3. Modify the configured signature algorithm and signing key:
        jwtBuilder.signWith("new_algorithm", new_key);
      4. Build the token by using the com.ibm.websphere.security.jwt.JwtToken API.
        JwtToken jwtToken = jwtBuilder.buildJwt();
        String jwtTokenString = jwtToken.compact();
        

JSON Web Token API examples

The following example creates a new JWT.
JwtBuilder jwtBuilder = JwtBuilder.create();
jwtBuilder.subject("tom@op.com").claim(Claims.AUDIENCE, "https://acme.com/rs").claim("iss","https://sso.com/ibm/op" ).claim("scope", "impersonator monitor").claim("uid", "hasys123haksiqws");
JwtToken goToken = jwtBuilder.buildJwt();
The resulting JWT is signed with the server's default private key and contains the following claims.
{
"aud": "https://acme.com/rs",
"iss": "https://sso.com/ibm/op",
"iat": 1388440863, "exp": 1388444763,
"uid": "hasys123haksiqws",
"sub": "tom@op.com",
"scope": "impersonator monitor"
}
The following example builds the newToken JWT from another JWT, goToken.
JwtToken newToken = JwtBuilder.create().claim(Claims.AUDIENCE, "https://acme.com/rs").claimFrom(goToken, "sub").claim(goToken, "uid").claim(goToken, "scope").buildJwt();