Contents
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).
<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@Claimannotation to оbtain the value of a claim by callinggetValue().
Configuration
MP-JWT Auth configuration is defined by the spec (options prefixed with `mp.jwt.`), and we add a few configuration options for the security provider (options prefixed with `security.providers.mp-jwt-auth.`)
Configuration options
| key | type | default value | description |
|---|---|---|---|
|
string (RSA-OAEP, RSA-OAEP-256) |
|
Expected key management algorithm supported by the MP JWT endpoint.
Supported algorithms are either Allowed values:
|
|
string |
|
Private key for decryption of encrypted claims. The value may be a relative path or a URL. |
|
string |
|
Specific cookie property name where we should search for JWT property. |
|
string |
|
Name of the header expected to contain the token. |
|
string[] |
|
Expected audiences of incoming tokens. |
|
int |
|
Clock skew to be accounted for in token expiration and max age validations in seconds. |
|
string |
|
Expected issuer in incoming requests. |
|
string |
|
String representation of the public key. |
|
string |
|
Path to public key. The value may be a relative path or a URL. |
|
int |
|
Maximal expected token age in seconds. If this value is set, |
|
boolean |
|
Whether to allow impersonation by explicitly overriding username from outbound requests using io.helidon.security.EndpointConfig.PROPERTY_OUTBOUND_ID property. By default this is not allowed and identity can only be propagated. |
|
string |
|
Default JWT key ID which should be used. |
|
|
Token handler to extract username from request.
Uses |
|
|
|
JWK resource for authenticating the request |
|
|
string |
|
Audience expected in inbound JWTs. |
|
string |
|
Path to public key. The value may be a relative path or a URL. |
|
boolean |
|
Whether to authenticate requests. |
|
boolean |
|
Whether to load JWK verification keys on server startup
Default value is |
|
boolean |
|
Whether authentication is required. By default, request will fail if the username cannot be extracted. If set to false, request will process and this provider will abstain. |
|
SubjectType (USER, SERVICE) |
|
Principal type this provider extracts (and also propagates). |
|
boolean |
|
Whether to propagate identity. |
|
|
Configuration of outbound rules. |
A configuration example in microprofile-config.properties:
mp.jwt.verify.issuer=https://{PublicIssuerDomain}/oauth2/default
mp.jwt.verify.publickey.location=${mp.jwt.verify.issuer}/v1/keys
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:
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:
TOKEN=sdf4dDSWFcswdsffDSasEgv...
Run the application and execute an http request against it:
curl -X GET -I -H "Authorization: Bearer $TOKEN" http://localhost:8080/hello
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