HelidonHelidon4.5.0

JWT

MicroProfile JWT Authentication

Overview

JSON Web Tokens (JWT) are an open, industry standard (RFC 7519) method for representing claims securely between two parties.

JSON Web Token defines a compact and self-contained way for securely transmitting information between parties as a JSON object. With JWT Auth you can integrate security features such as single sign on into your Helidon MP applications.

Maven Coordinates

To enable JWT Authentication, either add a dependency on the helidon-microprofile bundle or add the following dependency to your project’s pom.xml (see Managing Dependencies).

pom.xml
<dependency>
  <groupId>io.helidon.microprofile.jwt</groupId>
  <artifactId>helidon-microprofile-jwt-auth</artifactId>
</dependency>

Usage

The main configuration point for JWT Auth is a JAX-RS Application class. As this class is discovered using CDI, it must have a bean defining annotation.

Minimal required setup is done using @LoginConfig(authMethod = "MP-JWT"):

@LoginConfig(authMethod = "MP-JWT")
@ApplicationScoped
public class ProtectedApplication extends Application {
}

API

The following interfaces and annotations are used to work with JWT in Helidon MP:

  • JsonWebToken - an interface used in CDI beans (@RequestScoped) dependency injection to obtain the JWT of the currently executing caller.
  • @Claim - an annotation used by CDI bean (@RequestScoped) dependency injection to obtain individual claims from the caller’s JWT.
  • ClaimValue - a proxy interface used with @Claim annotation to obtain the value of a claim by calling getValue().

Configuration options

ValueTypeDefaultDescription
mp.jwt.decrypt.key.algorithm`StringExpected key management algorithm supported by the MP JWT endpoint
mp.jwt.decrypt.key.locationStringPrivate key for decryption of encrypted claims
mp.jwt.token.cookieStringBearerSpecific cookie property name where we should search for JWT property
mp.jwt.token.headerStringAuthorizationName of the header expected to contain the token
mp.jwt.verify.audiencesList<String>Expected audiences of incoming tokens
mp.jwt.verify.clock.skewInteger5Clock skew to be accounted for in token expiration and max age validations in seconds
mp.jwt.verify.issuerStringExpected issuer in incoming requests
mp.jwt.verify.publickeyStringString representation of the public key
mp.jwt.verify.publickey.locationStringPath to public key
mp.jwt.verify.token.ageIntegerMaximal expected token age in seconds
security.providers.mp-jwt-auth.allow-impersonationBooleanfalseWhether to allow impersonation by explicitly overriding username from outbound requests using io.helidon.security.EndpointConfig#PROPERTY_OUTBOUND_IDproperty
security.providers.mp-jwt-auth.atn-token.default-key-idStringDefault JWT key ID which should be used
security.providers.mp-jwt-auth.atn-token.handlerTokenHandlerToken handler to extract username from request
security.providers.mp-jwt-auth.atn-token.jwk.resourceResourceJWK resource for authenticating the request
security.providers.mp-jwt-auth.atn-token.jwt-audienceStringAudience expected in inbound JWTs
security.providers.mp-jwt-auth.atn-token.verify-keyStringPath to public key
security.providers.mp-jwt-auth.authenticateBooleeantrueWhether to authenticate requests
security.providers.mp-jwt-auth.load-on-startupBooleanfalseWhether to load JWK verification keys on server startup Default value is false
security.providers.mp-jwt-auth.optionalBooleanfalseWhether authentication is required
security.providers.mp-jwt-auth.principal-typeSubjectTypeUSERPrincipal type this provider extracts (and also propagates)
security.providers.mp-jwt-auth.jwt-groups-pathStringgroupsPath to the JWT payload claim containing groups to add as role grants. Nested object claims can be configured with slash-separated path segments, such as realm/groups
security.providers.mp-jwt-auth.jwt-groups-separatorStringSeparator used to split a string claim value into multiple groups. This is used only when jwt-groups-path is configured to a custom path other than groups; setting only jwt-groups-separator has no effect.
security.providers.mp-jwt-auth.propagateBooleantrueWhether to propagate identity
security.providers.mp-jwt-auth.sign-tokenOutboundConfigConfiguration of outbound rules

A configuration example in microprofile-config.properties:

microprofile-config.properties
mp.jwt.verify.issuer=https://{PublicIssuerDomain}/oauth2/default
mp.jwt.verify.publickey.location=${mp.jwt.verify.issuer}/v1/keys

Key Algorithm

Allowed values for mp.jwt.decrypt.key.algorithm:

ValueDescription
RSA-OAEPRSA-OAEP Algorithm
RSA-OAEP-256RSA-OAEP-256 Algorithm

Examples

@Path("/hello")
public class HelloResource {

    @GET
    @Produces(TEXT_PLAIN)
    public String hello(@Context SecurityContext context) {
        Optional<Principal> userPrincipal = context.userPrincipal();
        return "Hello, " + userPrincipal.get().getName() + "!";
    }
}

Do not forget to annotate the HelloApplication class to enable JWT:

@LoginConfig(authMethod = "MP-JWT")
@ApplicationScoped
public class HelloApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        return Set.of(HelloResource.class);
    }
}

Add the following configuration in microprofile-config.properties:

microprofile-config.properties
mp.jwt.verify.issuer=https://{IssuerPublicDomain}/oauth2/default
mp.jwt.verify.publickey.location=${mp.jwt.verify.issuer}/v1/keys

Obtain the Security Token from external issuer:

Terminal
TOKEN=sdf4dDSWFcswdsffDSasEgv...

Run the application and execute an http request against it:

Terminal
curl -X GET -I -H "Authorization: Bearer $TOKEN" http://localhost:8080/hello
Output
HTTP/1.1 200 OK
Date: 08.06.2022 10:33:47 EEST
connection: keep-alive
content-length: 28

Hello, secure@helidon.io!

Which means that the request successfully passed authentication.

Additional Information

Learn more about JWT authentication at:
Eclipse MicroProfile Interoperable JWT RBAC

Reference

Copyright © 2018, 2026 Oracle and/or its affiliates.