Interface TokenRequestHandlerSpi
-
- All Known Implementing Classes:
TokenRequestHandlerSpiAdapter
public interface TokenRequestHandlerSpiService Provider Interface to work withTokenRequestHandler.An implementation of this interface must be given to the constructor of
TokenRequestHandlerclass.- Author:
- Takahiko Kawasaki
-
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description StringauthenticateUser(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.ResponsejwtBearer(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.ResponsenativeSso(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.ResponsetokenExchange(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 ofusernameparameter in the token request.password- The value ofpasswordparameter in the token request.- Returns:
- The subject (= unique identifier) of the authenticated
end-user. If the pair of
usernameandpasswordis invalid,nullshould 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_tokentoken_typeexpires_inrefresh_tokenscopeerrorerror_descriptionerror_uriid_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_typeparameter contained in the token request from the client application isauthorization_codeorrefresh_token, extra properties are merged. Rules are as described in the table below.grant_typeDescription authorization_codeIf 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=1andb=2, and if this method returns two extra properties,a=Aandc=3, the resultant access token will have three extra properties,a=A,b=2andc=3.refresh_tokenIf 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
nullis 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
TokenResponsethat represents a response from Authlete's/auth/tokenAPI. The instance contains information about the token exchange request such as the value of thesubject_tokenrequest parameter. Implementations of thistokenExchangemethod 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/tokenAPI 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 theTokenResponseclass 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, thenativeSsomethod is called instead of thistokenExchangemethod. Native SSO is supported in Authlete 3.0 and newer versions.- Parameters:
tokenResponse- A response from Authlete's/auth/tokenAPI.headers- HTTP headers that should be included in the token response. For example, this map may include a key-value pair consisting of theDPoP-Nonceheader and a DPoP nonce value (see RFC 9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP), Section 8. Authorization Server-Provided Nonce). Thisheadersparameter 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,TokenRequestHandlerwill generate400 Bad Requestwith{"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
TokenResponsethat represents a response from Authlete's/auth/tokenAPI. The instance contains information about the token request such as the value of theassertionrequest parameter. Implementations of thisjwtBearermethod are supposed to (1) validate the authorization grant (= the JWT specified by theassertionrequest parameter), (2) generate an access token, and (3) prepare a token response in the JSON format that conforms to RFC 6749.Authlete's
/auth/tokenAPI 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 theTokenResponseclass 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/tokenAPI.headers- HTTP headers that should be included in the token response. For example, this map may include a key-value pair consisting of theDPoP-Nonceheader and a DPoP nonce value (see RFC 9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP), Section 8. Authorization Server-Provided Nonce). Thisheadersparameter 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,TokenRequestHandlerwill generate400 Bad Requestwith{"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
actionparameter in the response from Authlete's/auth/tokenAPI isNATIVE_SSO. This action value is returned when one of the following condition sets is satisfied.- Authorization Code Flow
- The service's
nativeSsoSupportedproperty is set totrue. - The service supports the
openidanddevice_ssoscopes. - The client is allowed to request the
openidanddevice_ssoscopes. - The grant type of the token request is
authorization_code. - The authorization request preceding the token request included the
openidanddevice_ssoscopes.
- The service's
- Refresh Token Flow
- The service's
nativeSsoSupportedproperty is set totrue. - The service supports the
device_ssoscope. - The client is allowed to request the
device_ssoscope. - The grant type of the token request is
refresh_token. - The access token issued by the refresh token request still covers the
device_ssoscope, 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
nativeSsoSupportedproperty 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_typerequest parameter isurn:openid:params:token-type:device-secret.
- The service's
Session ID
When the
actionvalue isNATIVE_SSO, the response from the/auth/tokenAPI contains asessionIdparameter. 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/issueAPI. 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_codeorrefresh_token, the response from the/auth/tokenAPI may contain adeviceSecretparameter. Its value represents a device secret passed from the client application as the value of thedevice_secretrequest parameter to the token endpoint. This request parameter is optional.When the
deviceSecretparameter in the response from the/auth/tokenAPI 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/nativessoAPI later without modification, unless the authorization server chooses to reissue a new device secret.On the other hand, if the
deviceSecretparameter 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/nativessoAPI.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/tokenAPI containsdeviceSecretanddeviceSecretHashparameters.The
deviceSecretparameter represents the device secret presented by the client application to the token endpoint as the value of theactor_tokenrequest parameter.The
deviceSecretHashparameter represents the device secret hash embedded as the value of theds_hashclaim in the ID token that the client application passed to the token endpoint as the value of thesubject_tokenrequest 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_hashanddevice_secretis 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./nativessoAPI CallAfter validating the session ID, device secret, and device secret hash as necessary, the authorization server must call the
/nativessoAPI to generate a Native SSO-compliant ID token and token response. The API expects the following request parameters.Parameter Description accessTokenREQUIRED. If the response from the
/auth/tokenAPI contains thejwtAccessTokenparameter, its value must be used as the value of thisaccessTokenrequest parameter to the/nativessoAPI. If thejwtAccessTokenparameter is absent, the value of theaccessTokenparameter in the response from the/auth/tokenAPI should be used instead.The specified value is used as the value of the
access_tokenproperty in the token response.refreshTokenOPTIONAL. If the
refreshTokenparameter is present in the response from the/auth/tokenAPI, its value should be specified as the value of thisrefreshTokenrequest parameter to the/nativessoAPI. Note that whether a refresh token is issued depends on configuration.The specified value is used as the value of the
refresh_tokenproperty in the token response.deviceSecretREQUIRED. If the response from the
/auth/tokenAPI contains thedeviceSecretparameter, its value should be used as the value of thisdeviceSecretrequest parameter to the/nativessoAPI. 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/tokenAPI does not contain thedeviceSecretparameter, or if its value is invalid, the authorization server must generate a new device secret and specify it in thedeviceSecretparameter to the/nativessoAPI.The specified value is used as the value of the
device_secretproperty in the token response.deviceSecretHashRECOMMENDED. 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
deviceSecretHashrequest parameter to the/nativessoAPI.When the
deviceSecretHashparameter is omitted, the implementation of the/nativessoAPI 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 thedeviceSecretHashparameter is omitted.subOPTIONAL. The value of the
subclaim to be embedded in the ID token. If omitted, the subject associated with the access token is used as the value of thesubclaim.claimsOPTIONAL. Additional claims to be embedded in the ID token. The format of this parameter must be a JSON object.
idtHeaderParamsOPTIONAL. Additional parameters to be embedded in the JWS header of the ID token. The format of this parameter must be a JSON object.
idTokenAudTypeOPTIONAL. This parameter specifies the type of the
audclaim in the ID token. If"array"is specified, theaudclaim will be a JSON array. If"string"is specified, it will be a JSON string. If omitted, theaudclaim will default to a JSON array.On success, the
actionparameter in the response from the/nativessoAPI isOK. In this case, the value of theresponseContentparameter 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" }- Parameters:
tokenResponse- A response from Authlete's/auth/tokenAPI.headers- HTTP headers that should be included in the token response. For example, this map may include a key-value pair consisting of theDPoP-Nonceheader 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
-
-