Interface TokenRequestHandlerSpi
-
- All Known Implementing Classes:
TokenRequestHandlerSpiAdapter
public interface TokenRequestHandlerSpi
Service Provider Interface to work withTokenRequestHandler
.An implementation of this interface must be given to the constructor of
TokenRequestHandler
class.- Author:
- Takahiko Kawasaki
-
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description String
authenticateUser(String username, String password)
Authenticate an end-user.com.authlete.common.dto.Property[]
getProperties()
Get extra properties to associate with an access token.javax.ws.rs.core.Response
jwtBearer(com.authlete.common.dto.TokenResponse tokenResponse, Map<String,Object> headers)
Handle a token request that uses the grant type"urn:ietf:params:oauth:grant-type:jwt-bearer"
(RFC 7523).javax.ws.rs.core.Response
nativeSso(com.authlete.common.dto.TokenResponse tokenResponse, Map<String,Object> headers)
Handle a token request that complies with the "OpenID Connect Native SSO for Mobile Apps 1.0" specification (also known as "Native SSO").javax.ws.rs.core.Response
tokenExchange(com.authlete.common.dto.TokenResponse tokenResponse, Map<String,Object> headers)
Handle a token exchange request.
-
-
-
Method Detail
-
authenticateUser
String authenticateUser(String username, String password)
Authenticate an end-user.This method is called only when Resource Owner Password Credentials Grant was used. Therefore, if you have no mind to support Resource Owner Password Credentials, always return
null
. In typical cases, you don't have to support Resource Owner Password Credentials Grant. FYI: RFC 6749 says "The authorization server should take special care when enabling this grant type and only allow it when other flows are not viable."Below is an example implementation using Apache Shiro.
@Override public String authenticateUser(String username, String password) { // Pack the username and password into AuthenticationToken // which Apache Shiro's SecurityManager can accept. AuthenticationToken credentials = new UsernamePasswordToken(username, password); try { // Authenticate the resource owner. AuthenticationInfo info = SecurityUtils.getSecurityManager().authenticate(credentials); // Get the subject of the authenticated user. return info.getPrincipals().getPrimaryPrincipal().toString(); } catch (AuthenticationException e) { // Not authenticated. return null; } }
- Parameters:
username
- The value ofusername
parameter in the token request.password
- The value ofpassword
parameter in the token request.- Returns:
- The subject (= unique identifier) of the authenticated
end-user. If the pair of
username
andpassword
is invalid,null
should be returned.
-
getProperties
com.authlete.common.dto.Property[] getProperties()
Get extra properties to associate with an access token.This method is expected to return an array of extra properties. The following is an example that returns an array containing one extra property.
@Override public
Property
[] getProperties() { return newProperty
[] { newProperty
("example_parameter", "example_value") }; }Extra properties returned from this method will appear as top-level entries in a JSON response from an authorization server as shown in 5.1. Successful Response in RFC 6749.
Keys listed below should not be used and they would be ignored on the server side even if they were used. It's because they are reserved in RFC 6749 and OpenID Connect Core 1.0.
access_token
token_type
expires_in
refresh_token
scope
error
error_description
error_uri
id_token
Note that there is an upper limit on the total size of extra properties. On the server side, the properties will be (1) converted to a multidimensional string array, (2) converted to JSON, (3) encrypted by AES/CBC/PKCS5Padding, (4) encoded by base64url, and then stored into the database. The length of the resultant string must not exceed 65,535 in bytes. This is the upper limit, but we think it is big enough.
When the value of
grant_type
parameter contained in the token request from the client application isauthorization_code
orrefresh_token
, extra properties are merged. Rules are as described in the table below.grant_type
Description authorization_code
If the authorization code presented by the client application already has extra properties (this happens if
AuthorizationDecisionHandlerSpi.getProperties()
returned extra properties when the authorization code was issued), extra properties returned by this method will be merged into the existing extra properties. Note that the existing extra properties will be overwritten if extra properties returned by this method have the same keys.For example, if an authorization code has two extra properties,
a=1
andb=2
, and if this method returns two extra properties,a=A
andc=3
, the resultant access token will have three extra properties,a=A
,b=2
andc=3
.refresh_token
If the access token associated with the refresh token presented by the client application already has extra properties, extra properties returned by this method will be merged into the existing extra properties. Note that the existing extra properties will be overwritten if extra properties returned by this method have the same keys.
- Returns:
- Extra properties. If
null
is returned, any extra property will not be associated. - Since:
- 1.3
-
tokenExchange
javax.ws.rs.core.Response tokenExchange(com.authlete.common.dto.TokenResponse tokenResponse, Map<String,Object> headers)
Handle a token exchange request.This method is called when the grant type of the token request is
"urn:ietf:params:oauth:grant-type:token-exchange"
(but see the "NOTE 2" below). The grant type is defined in RFC 8693: OAuth 2.0 Token Exchange.RFC 8693 is very flexible. In other words, the specification does not define details that are necessary for secure token exchange. Therefore, implementations have to complement the specification with their own rules.
The argument passed to this method is an instance of
TokenResponse
that represents a response from Authlete's/auth/token
API. The instance contains information about the token exchange request such as the value of thesubject_token
request parameter. Implementations of thistokenExchange
method are supposed to (1) validate the information based on their own rules, (2) generate a token (e.g. an access token) using the information, and (3) prepare a token response in the JSON format that conforms to Section 2.2 of RFC 8693.Authlete's
/auth/token
API performs validation of token exchange requests to some extent. Therefore, authorization server implementations don't have to repeat the same validation steps. See the JavaDoc of theTokenResponse
class for details about the validation steps.NOTE 1: Token Exchange is supported by Authlete 2.3 and newer versions. If the Authlete server of your system is older than version 2.3, the grant type (
"urn:ietf:params:oauth:grant-type:token-exchange"
) is not supported and so this method is never called.NOTE 2: Even if the grant type is
"urn:ietf:params:oauth:grant-type:token-exchange"
, if the service is configured to support the "OpenID Connect Native SSO for Mobile Apps 1.0" specification (a.k.a. "Native SSO") and the token request complies with the specification, thenativeSso
method is called instead of thistokenExchange
method. Native SSO is supported in Authlete 3.0 and newer versions.- Parameters:
tokenResponse
- A response from Authlete's/auth/token
API.headers
- HTTP headers that should be included in the token response. For example, this map may include a key-value pair consisting of theDPoP-Nonce
header and a DPoP nonce value (see RFC 9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP), Section 8. Authorization Server-Provided Nonce). Thisheaders
parameter was introduced in version 2.86 of authlete-java-jaxrs. This is a breaking change.- Returns:
- A response from the token endpoint. It must conform to Section
2.2 of RFC 8693. If this method returns
null
,TokenRequestHandler
will generate400 Bad Request
with{"error":"unsupported_grant_type"}
. - Since:
- 2.47, Authlete 2.3
- See Also:
- RFC 8693 OAuth 2.0 Token Exchange
-
jwtBearer
javax.ws.rs.core.Response jwtBearer(com.authlete.common.dto.TokenResponse tokenResponse, Map<String,Object> headers)
Handle a token request that uses the grant type"urn:ietf:params:oauth:grant-type:jwt-bearer"
(RFC 7523).This method is called when the grant type of the token request is
"urn:ietf:params:oauth:grant-type:jwt-bearer"
. The grant type is defined in RFC 7523: JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants.The grant type utilizes a JWT as an authorization grant, but the specification does not define details about how the JWT is generated by whom. As a result, it is not defined in the specification how to obtain the key whereby to verify the signature of the JWT. Therefore, each deployment has to define their own rules which are necessary to determine the key for signature verification.
The argument passed to this method is an instance of
TokenResponse
that represents a response from Authlete's/auth/token
API. The instance contains information about the token request such as the value of theassertion
request parameter. Implementations of thisjwtBearer
method are supposed to (1) validate the authorization grant (= the JWT specified by theassertion
request parameter), (2) generate an access token, and (3) prepare a token response in the JSON format that conforms to RFC 6749.Authlete's
/auth/token
API performs validation of token requests to some extent. Therefore, authorization server implementations don't have to repeat the same validation steps. Basically, what implementations have to do is to verify the signature of the JWT. See the JavaDoc of theTokenResponse
class for details about the validation steps.NOTE: JWT Authorization Grant is supported by Authlete 2.3 and newer versions. If the Authlete server of your system is older than version 2.3, the grant type (
"urn:ietf:params:oauth:grant-type:jwt-bearer"
) is not supported and so this method is never called.- Parameters:
tokenResponse
- A response from Authlete's/auth/token
API.headers
- HTTP headers that should be included in the token response. For example, this map may include a key-value pair consisting of theDPoP-Nonce
header and a DPoP nonce value (see RFC 9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP), Section 8. Authorization Server-Provided Nonce). Thisheaders
parameter was introduced in version 2.86 of authlete-java-jaxrs. This is a breaking change.- Returns:
- A response from the token endpoint. It must conform to RFC 6749. If
this method returns
null
,TokenRequestHandler
will generate400 Bad Request
with{"error":"unsupported_grant_type"}
. - Since:
- 2.48, Authlete 2.3
- See Also:
- RFC 7521 Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants, RFC 7523 JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
-
nativeSso
javax.ws.rs.core.Response nativeSso(com.authlete.common.dto.TokenResponse tokenResponse, Map<String,Object> headers)
Handle a token request that complies with the "OpenID Connect Native SSO for Mobile Apps 1.0" specification (also known as "Native SSO").This method is called if the
action
parameter in the response from Authlete's/auth/token
API isNATIVE_SSO
. This action value is returned when one of the following condition sets is satisfied.- Authorization Code Flow
- The service's
nativeSsoSupported
property is set totrue
. - The service supports the
openid
anddevice_sso
scopes. - The client is allowed to request the
openid
anddevice_sso
scopes. - The grant type of the token request is
authorization_code
. - The authorization request preceding the token request included the
openid
anddevice_sso
scopes.
- The service's
- Refresh Token Flow
- The service's
nativeSsoSupported
property is set totrue
. - The service supports the
device_sso
scope. - The client is allowed to request the
device_sso
scope. - The grant type of the token request is
refresh_token
. - The access token issued by the refresh token request still covers the
device_sso
scope, even if the scope coverage might have been narrowed. - The presented refresh token is associated with a user's authentication session. (In practice, only refresh tokens generated through the authorization code flow compliant with Native SSO can be used.)
- The service's
- Token Exchange Flow
- The service's
nativeSsoSupported
property is set totrue
. - The grant type of the token request is
urn:ietf:params:oauth:grant-type:token-exchange
. - The value of the
actor_token_type
request parameter isurn:openid:params:token-type:device-secret
.
- The service's
Session ID
When the
action
value isNATIVE_SSO
, the response from the/auth/token
API contains asessionId
parameter. Its value represents a user's authentication session - that is, a session ID.The authorization server must check whether the session ID is still valid. Note that the session ID is not a value generated by Authlete but one that was passed from the authorization server to the
/auth/authorization/issue
API. Therefore, Authlete does not and cannot determine whether the session ID is still valid.If the session ID is no longer valid, the authorization server should return an error response from the token endpoint with the error code
invalid_grant
.Device Secret
Case 1: Device Secret in Authorization Code and Refresh Token Flows
When the grant type is
authorization_code
orrefresh_token
, the response from the/auth/token
API may contain adeviceSecret
parameter. Its value represents a device secret passed from the client application as the value of thedevice_secret
request parameter to the token endpoint. This request parameter is optional.When the
deviceSecret
parameter in the response from the/auth/token
API is not null, the authorization server must check whether the device secret is valid. If the device secret is valid, the value should be passed to the/nativesso
API later without modification, unless the authorization server chooses to reissue a new device secret.On the other hand, if the
deviceSecret
parameter is absent or its value is invalid, the authorization server must generate a new device secret. The new value should then be passed to the/nativesso
API.Note that Authlete neither generates nor manages device secrets. It is the authorization server's responsibility to do so. Therefore, Authlete does not and cannot determine whether a device secret is valid.
Case 2: Device Secret in Token Exchange Flow
When the grant type is
urn:ietf:params:oauth:grant-type:token-exchange
, the response from the/auth/token
API containsdeviceSecret
anddeviceSecretHash
parameters.The
deviceSecret
parameter represents the device secret presented by the client application to the token endpoint as the value of theactor_token
request parameter.The
deviceSecretHash
parameter represents the device secret hash embedded as the value of theds_hash
claim in the ID token that the client application passed to the token endpoint as the value of thesubject_token
request parameter.The authorization server must verify the binding between the device secret and device secret hash. If the binding fails verification, the authorization server should return an error response from the token endpoint with the error code
invalid_grant
.Note that the Native SSO specification does not define how to compute a device secret hash value from a device secret. The specification states, "The exact binding between the
ds_hash
anddevice_secret
is not specified by this profile." Therefore, the authorization server must define a rule regarding for computing the device hash value and verify the binding based on that rule. A simple example of hash computation logic is to compute the SHA-256 hash of a device secret and base64url-encode the hash./nativesso
API CallAfter validating the session ID, device secret, and device secret hash as necessary, the authorization server must call the
/nativesso
API to generate a Native SSO-compliant ID token and token response. The API expects the following request parameters.Parameter Description accessToken
REQUIRED. If the response from the
/auth/token
API contains thejwtAccessToken
parameter, its value must be used as the value of thisaccessToken
request parameter to the/nativesso
API. If thejwtAccessToken
parameter is absent, the value of theaccessToken
parameter in the response from the/auth/token
API should be used instead.The specified value is used as the value of the
access_token
property in the token response.refreshToken
OPTIONAL. If the
refreshToken
parameter is present in the response from the/auth/token
API, its value should be specified as the value of thisrefreshToken
request parameter to the/nativesso
API. Note that whether a refresh token is issued depends on configuration.The specified value is used as the value of the
refresh_token
property in the token response.deviceSecret
REQUIRED. If the response from the
/auth/token
API contains thedeviceSecret
parameter, its value should be used as the value of thisdeviceSecret
request parameter to the/nativesso
API. The authorization server may choose to issue a new device secret; in that case, it is free to generate a new device secret and specify the new value.If the response from the
/auth/token
API does not contain thedeviceSecret
parameter, or if its value is invalid, the authorization server must generate a new device secret and specify it in thedeviceSecret
parameter to the/nativesso
API.The specified value is used as the value of the
device_secret
property in the token response.deviceSecretHash
RECOMMENDED. The authorization server should compute the hash value of the device secret based on its own logic and specify the computed hash as the value of this
deviceSecretHash
request parameter to the/nativesso
API.When the
deviceSecretHash
parameter is omitted, the implementation of the/nativesso
API generates the device secret hash by computing the SHA-256 hash of the device secret and encoding it with base64url. Note that this hash computation logic is not a rule defined in the Native SSO specification; rather, it is Authlete-specific fallback logic used when thedeviceSecretHash
parameter is omitted.sub
OPTIONAL. The value of the
sub
claim to be embedded in the ID token. If omitted, the subject associated with the access token is used as the value of thesub
claim.claims
OPTIONAL. Additional claims to be embedded in the ID token. The format of this parameter must be a JSON object.
idtHeaderParams
OPTIONAL. Additional parameters to be embedded in the JWS header of the ID token. The format of this parameter must be a JSON object.
idTokenAudType
OPTIONAL. This parameter specifies the type of the
aud
claim in the ID token. If"array"
is specified, theaud
claim will be a JSON array. If"string"
is specified, it will be a JSON string. If omitted, theaud
claim will default to a JSON array.On success, the
action
parameter in the response from the/nativesso
API isOK
. In this case, the value of theresponseContent
parameter in the response can be used as the message body of the token response from the token endpoint. The token endpoint implementation can construct the token response as follows:HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-cache, no-store (Embed the value of the responseContent parameter in the response from the /nativesso API here)
The resulting message body will look like this:
{ "access_token": "(Access Token)", "token_type": "(Token Type)", "expires_in": (Lifetime in Seconds), "scope": "(Space-separated Scopes)", "refresh_token": "(Refresh Token)", "id_token": "(ID Token)", "device_secret": "(Device Secret)", "issued_token_type": "urn:ietf:params:oauth:token-type:access_token" }
The
issued_token_type
parameter in the token response is required only in the token exchange flow, but the current implementation of the/nativesso
API always embeds the parameter, even in the authorization code and refresh token flows. Since it is allowed to include any parameters in token responses, this behavior should not cause any issues.- Parameters:
tokenResponse
- A response from Authlete's/auth/token
API.headers
- HTTP headers that should be included in the token response. For example, this map may include a key-value pair consisting of theDPoP-Nonce
header and a DPoP nonce value (see RFC 9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP), Section 8. Authorization Server-Provided Nonce).- Returns:
- A response from the token endpoint. It must conform to the "OpenID Connect Native SSO for Mobile Apps 1.0" specification.
- Since:
- 2.86, Authlete 3.0
- See Also:
- OpenID Connect Native SSO for Mobile Apps 1.0
- Authorization Code Flow
-
-