JWT plug-in - JWTToken AuthState
Introduction and overview
JWT (JSON Web Token) is a compact and URL-safe format to represent claims and transfer them between two parties. For instance, JWT may be used as an alternative to Nevis SecTokens and SAML tokens to delegate a user identity to back-end applications.
Claims are always signed or encrypted. Plain-text JWT tokens are currently not supported. JWT tokens are encapsulated in a JWS (JSON Web Signature) or JWE (JSON Web Encryption) structure respectively.
The JWTToken AuthState supports the use of the JWT token.
The auth state automatically generates the X.509 certificate SHA-256 thumbprint header parameter x5t#S256
according to RFC-7515 for signing keys.
In case a backend has issues with this header parameter, the following system property can be used to disable the automatic thumbprint header parameter generation: ch.nevis.auth.jwttoken.x5t.disabled=true
We recommend not to use this property, especially for long-term setups and rather invest in getting the affected backend to behave according to the JWT specifications.
Description
The following table and chapters describe the characteristics of the AuthState.
Topic | Description |
---|---|
Class | ch.nevis.esauth.auth.states.jwt.JWTToken |
Logging | JWT |
Auditing | none |
Marker | none |
Methods | authenticate, stepup, unlock |
Properties
token.type
(string, "JWS")`Type of JWT token. Has to be either "JWS" (JSON Web Signature) or "JWE" (JSON Web Encryption).
token.outputAttributeName
(string, "out.JWTToken")Name of the attribute storing the JWT token in the specified scope.
token.outputAttributeScope
(string, "outargs")Scope where the output JWT token will be stored with the specified attribute name. Same scopes can be used as with the TransformAttributes auth state.
token.header.includeType
(boolean, "false")Flag that specifies whether the header type "JWT" is included or not. I.e., if set to "true" the JWT token header property: "typ": "JWT" will be included.
token.algorithm
(string, "HS256")Algorithm to generate the encryption or signing key (included in the JWT header as "alg" parameter).
All required and recommended algorithms are supported. See the table below for a complete listing.
Identifier | Description | Symmetry |
---|---|---|
JWS algorithms | ||
HS256 | HMAC using SHA-256 hash algorithm | Symmetric |
HS384 | HMAC using SHA-384 hash algorithm | Symmetric |
HS512 | HMAC using SHA-512 hash algorithm | Symmetric |
RS256 | RSASSA-PKCS-v1_5 using SHA-256 hash algorithm | Asymmetric |
RS384 | RSASSA-PKCS-v1_5 using SHA-384 hash algorithm | Asymmetric |
RS512 | RSASSA-PKCS-v1_5 using SHA-512 hash algorithm | Asymmetric |
JWE algorithm | ||
RSA1_5 | RSAES-PKCS1-V1_5 | Asymmetric |
RSA-OAEP | RSAES using Optimal Asymmetric Encryption Padding (OAEP) | Asymmetric |
RSA-OAEP-256 | RSAES using Optimal Asymmetric Encryption Padding (OAEP) with the SHA-256 hash function and the MGF1 with SHA-256 mask generation function | Asymmetric |
token.encryptionMethod
(string, "A256GCM")Algorithm for encryption of the plain-text JWT payload. This property is only relevant for JWE tokens and will be included in the JWE header as "enc" parameter.
All required and recommended algorithms are supported. Refer to the table below for a complete listing.
Identifier | Description | Symmetry |
---|---|---|
A128CBC-HS256 | AES_128_CBC_HMAC_SHA_256 authenticated encryption using a 256 bit key | Symmetric |
A256CBC-HS512 | AES_256_CBC_HMAC_SHA_512 authenticated encryption using a 512 bit key | Symmetric |
A128GCM | AES in Galois/Counter Mode (GCM) (NIST.800-38D) using a 128 bit key | Symmetric |
A256GCM | AES in Galois/Counter Mode (GCM) (NIST.800-38D) using a 256 bit key | Symmetric |
token.kid
(string, -)Optional key ID header parameter, which is a hint indicating the key used to secure the JWS. The parameter allows originators to explicitly signal a change of key to recipients.
keystoreref
(string, "DefaultKeyStore")Create a keystore with the required key material and configure these properties accordingly to encrypt the JWE using the public key of the receiver or sign the JWS using the private key of nevisAuth.
Required if an asymmetric algorithm (e.g., RS256) is used.
keyobjectref
(string, "DefaultSigner")keycurve
(string, -)The curve's name of EC (Elliptic Curve) key. This is only used in case the private key is not extractable from HSM.
Possible values:
P-256
,secp256k1
,P-384
,P-521
,Ed25519
,Ed448
,X25519
,X448
.token.key
(String, -)Shared secret for symmetric algorithms.
Required if a symmetric algorithm (e.g., HS256) is used.
out.issuer
(string, "nevis")Value of "iss" claim.
out.subject
(string, "${request:userId}")Include ID of authenticated user as "sub" claim.
out.audience
(string, -)An arbitrary string which will be included as "aud" claim. Back-end applications may check if they belong to this audience.
You can use JSON syntax to specify multiple values. Examples:
<property name="out.audience" value="value1,value2"/>
Generates a single value ("value1,value2") for "aud".
<property name="out.audience" value="["value1", "value2"]"/>
Generates two values ("value1" and "value2") for "aud".
out.include.jwtId
(boolean, "false")Add JWT ID to claim set.
out.include.not_before
(boolean, "true")Defines whether the "nbf" (not before) claim is included in the JWT token.
The nbf claim identifies the time before which the JWT token must not be accepted for processing.
out.valid_before
(seconds, 10)Number of seconds this JWT token should be valid before the issue time
out.include.issued_at
(boolean, "true")Defines whether the "iat" (issued at) claim is included in the JWT token.
The iat claim identifies the time at which the JWT token was issued.
out.time_to_live
(seconds, 7200)Defines the number of seconds (since issuing time) that the JWT token should be valid. This attribute defines the "exp" claim in the JWT token.
If you want to generate a token with no expiration time (that is, with no "exp" claim defined), set "none" as the value of the out.time_to_live attribute.
You can use regular expressions to define the time to live. Examples:
The issued tokens will expire on 1st January 2020<property name="out.time_to_live" value="#{Math.round((nowJoda.withYear(2020).withMonthOfYear(1).withDayOfMonth(1).withTimeAtStartOfDay().getMillis() - nowJoda.getMillis()) / 1000)}"/>
The issued tokens have no expiration date<property name="out.time_to_live" value="none"/>
out.custom.*
(string, -)Use to add a custom JWT claim (e.g., e-mail address of the user)
You can use JSON syntax to specify arrays and JSON values.
Examples:
Generate a single value ('value1,value2') for 'myattr'<property name="out.custom.myattr" value="value1,value2"/>
Generate a single value ('null') for 'myattr'<property name="out.custom.myattr" value="null"/>
Generate an array with three values (1, 'value2' and null) for 'myattr'<property name="out.custom.myattr" value="[1,"value2",null]"/>
Generates a JSON object with one attribute named 'attr1' with a value ('value1') for 'myattr'<property name="out.custom.myattr" value="{"attr1,":"value1"}"/>
Input
none
Transitions
ok
A transition to the next state is expected)
Output
See property token.identifier
Errors
none
Notes
none
Example
<AuthState name="JWTToken" class="ch.nevis.esauth.auth.states.jwt.JWTToken" final="false">
<ResultCond name="ok" next="AuthDone"/>
<Response value="AUTH_ERROR"/>
<property name="out.audience" value="https://www.adnovum.ch"/>
<property name="out.issuer" value="https://my.nevis.server"/>
<property name="token.key" value="mustFulfillMinimalSizeDependingOnAlgorithmright"/>
</AuthState>