
com.authlete.jaxrs.spi.TokenRequestHandlerSpi Maven / Gradle / Ivy
Show all versions of authlete-java-jaxrs Show documentation
/*
* Copyright (C) 2015-2022 Authlete, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package com.authlete.jaxrs.spi;
import javax.ws.rs.core.Response;
import com.authlete.common.dto.Property;
import com.authlete.common.dto.TokenResponse;
import com.authlete.jaxrs.TokenRequestHandler;
/**
* Service Provider Interface to work with {@link
* com.authlete.jaxrs.TokenRequestHandler TokenRequestHandler}.
*
*
* An implementation of this interface must be given to the constructor
* of {@link com.authlete.jaxrs.TokenRequestHandler TokenRequestHandler}
* class.
*
*
* @author Takahiko Kawasaki
*/
public interface TokenRequestHandlerSpi
{
/**
* 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 {@code 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;
* }
* }
*
*
* @param username
* The value of {@code username} parameter in the token request.
*
* @param password
* The value of {@code password} parameter in the token request.
*
* @return
* The subject (= unique identifier) of the authenticated
* end-user. If the pair of {@code username} and {@code
* password} is invalid, {@code null} should be returned.
*/
String authenticateUser(String username, String password);
/**
* 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 {@link Property}[] getProperties()
* {
* return new {@link Property}[] {
* new {@link Property#Property(String, String)
* Property}("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.
*
*
*
* - {@code access_token}
*
- {@code token_type}
*
- {@code expires_in}
*
- {@code refresh_token}
*
- {@code scope}
*
- {@code error}
*
- {@code error_description}
*
- {@code error_uri}
*
- {@code 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 {@code grant_type} parameter contained in the token request
* from the client application is {@code authorization_code} or {@code refresh_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 {@link
* 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, {@code a=1}
* and {@code b=2}, and if this method returns two extra properties, {@code a=A}
* and {@code c=3}, the resultant access token will have three extra properties,
* {@code a=A}, {@code b=2} and {@code c=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.
*
*
*
*
*
*
* @return
* Extra properties. If {@code null} is returned, any extra
* property will not be associated.
*
* @since 1.3
*/
Property[] getProperties();
/**
* Handle a token exchange request.
*
*
* This method is called when the grant type of the token request is
* {@code "urn:ietf:params:oauth:grant-type:token-exchange"}. 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 {@link TokenResponse}
* that represents a response from Authlete's {@code /auth/token} API. The
* instance contains information about the token exchange request such as
* the value of the {@code subject_token} request parameter. Implementations
* of this {@code tokenExchange} 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 {@code /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 the
* {@link TokenResponse} class for details about the validation steps.
*
*
*
* NOTE: 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 ({@code "urn:ietf:params:oauth:grant-type:token-exchange"}) is not
* supported and so this method is never called.
*
*
* @param tokenResponse
* A response from Authlete's {@code /auth/token} API.
*
* @return
* A response from the token endpoint. It must conform to Section
* 2.2 of RFC 8693. If this method returns {@code null},
* {@link TokenRequestHandler} will generate {@code 400 Bad Request}
* with {"error":"unsupported_grant_type"}
.
*
* @since 2.47
* @since Authlete 2.3
*
* @see RFC 8693 OAuth 2.0 Token Exchange
*/
Response tokenExchange(TokenResponse tokenResponse);
/**
* Handle a token request that uses the grant type
* {@code "urn:ietf:params:oauth:grant-type:jwt-bearer"} (RFC 7523).
*
*
* This method is called when the grant type of the token request is
* {@code "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 {@link TokenResponse}
* that represents a response from Authlete's {@code /auth/token} API. The
* instance contains information about the token request such as the value
* of the {@code assertion} request parameter. Implementations of this
* {@code jwtBearer} method are supposed to (1) validate the authorization
* grant (= the JWT specified by the {@code assertion} request parameter),
* (2) generate an access token, and (3) prepare a token response in the
* JSON format that conforms to RFC 6749.
*
*
*
* Authlete's {@code /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 the
* {@link TokenResponse} 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 ({@code "urn:ietf:params:oauth:grant-type:jwt-bearer"})
* is not supported and so this method is never called.
*
*
* @param tokenResponse
* A response from Authlete's {@code /auth/token} API.
*
* @return
* A response from the token endpoint. It must conform to RFC 6749. If
* this method returns {@code null}, {@link TokenRequestHandler}
* will generate {@code 400 Bad Request} with
* {"error":"unsupported_grant_type"}
.
*
* @since 2.48
* @since Authlete 2.3
*
* @see RFC 7521
* Assertion Framework for OAuth 2.0 Client Authentication and
* Authorization Grants
*
* @see RFC 7523
* JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication
* and Authorization Grants
*/
Response jwtBearer(TokenResponse tokenResponse);
}