diff --git a/pom.xml b/pom.xml index f3ad8f8..65b5666 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ UTF-8 - 4.1 + 4.16 2.10.1 9.31 3.1.0 diff --git a/src/main/java/com/authlete/jakarta/AccessTokenValidator.java b/src/main/java/com/authlete/jakarta/AccessTokenValidator.java index 2e943cb..f5d7ce1 100644 --- a/src/main/java/com/authlete/jakarta/AccessTokenValidator.java +++ b/src/main/java/com/authlete/jakarta/AccessTokenValidator.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2023 Authlete, Inc. + * Copyright (C) 2016-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.IntrospectionRequest; import com.authlete.common.dto.IntrospectionResponse; import com.authlete.common.dto.IntrospectionResponse.Action; @@ -46,7 +47,7 @@ public class AccessTokenValidator extends BaseHandler */ public static class Params implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 2L; private String accessToken; @@ -56,6 +57,7 @@ public static class Params implements Serializable private String dpop; private String htm; private String htu; + private Options options; /** @@ -317,6 +319,39 @@ public Params setHtu(String htu) return this; } + + + /** + * Get the request options for the {@code /api/auth/introspection} API. + * + * @return + * The request options for the {@code /api/auth/introspection} API. + * + * @since 2.82 + */ + public Options getOptions() + { + return options; + } + + + /** + * Set the request options for the {@code /api/auth/introspection} API. + * + * @param options + * The request options for the {@code /api/auth/introspection} API. + * + * @return + * {@code this} object. + * + * @since 2.82 + */ + public Params setOptions(Options options) + { + this.options = options; + + return this; + } } @@ -337,16 +372,8 @@ public AccessTokenValidator(AuthleteApi api) /** - * Validate an access token. This method is an alias of the - * {@link #validate(Params)} method. - * - *

- * When the given access token is not valid, this method throws a - * {@link WebApplicationException}. The response contained in the - * exception complies with the requirements described in RFC 6750 (The OAuth - * 2.0 Authorization Framework: Bearer Token Usage). - *

+ * Validate an access token. This method is an alias of + * {@link #validate(String, Options) validate}{@code (accessToken, (Options)null)}. * * @param accessToken * An access token to validate. @@ -360,25 +387,38 @@ public AccessTokenValidator(AuthleteApi api) */ public AccessTokenInfo validate(String accessToken) throws WebApplicationException { - Params params = new Params() - .setAccessToken(accessToken) - ; - - return validate(params); + return validate(accessToken, (Options)null); } /** - * Validate an access token. This method is an alias of the - * {@link #validate(Params)} method. + * Validate an access token. This method is an alias of {@link + * #validate(String, String[], Options) validate}{@code (accessToken, null, options)}. * - *

- * When the given access token is not valid, this method throws a - * {@link WebApplicationException}. The response contained in the - * exception complies with the requirements described in RFC 6750 (The OAuth - * 2.0 Authorization Framework: Bearer Token Usage). - *

+ * @param accessToken + * An access token to validate. + * + * @param options + * The request options for the {@code /api/auth/introspection} API. + * + * @return + * Information about the access token. + * + * @throws WebApplicationException + * The access token is invalid. To be concrete, the access + * token does not exist or it has expired. + * + * @since 2.82 + */ + public AccessTokenInfo validate(String accessToken, Options options) throws WebApplicationException + { + return validate(accessToken, null, options); + } + + + /** + * Validate an access token. This method is an alias of + * {@link #validate(String, String[], Options) validate}{@code (accessToken, requiredScopes, null)}. * * @param accessToken * An access token to validate. @@ -402,18 +442,93 @@ public AccessTokenInfo validate(String accessToken) throws WebApplicationExcepti public AccessTokenInfo validate( String accessToken, String[] requiredScopes) throws WebApplicationException { - Params params = new Params() - .setAccessToken(accessToken) - .setRequiredScopes(requiredScopes) - ; + return validate(accessToken, requiredScopes, null); + } - return validate(params); + + /** + * Validate an access token. This method is an alias of + * {@link #validate(String, String[], String, String, Options) validate}{@code + * (accessToken, requiredScopes, null, null, options)}. + * + * @param accessToken + * An access token to validate. + * + * @param requiredScopes + * Scopes that must be associated with the access token. + * {@code null} is okay. + * + * @param options + * The request options for the {@code /api/auth/introspection} API. + * + * @return + * Information about the access token. + * + * @throws WebApplicationException + * The access token is invalid. To be concrete, one or more of + * the following conditions meet. + *
    + *
  1. The access token does not exist. + *
  2. The access token has expired. + *
  3. The access token does not cover the required scopes. + *
+ * + * @since 2.82 + */ + public AccessTokenInfo validate( + String accessToken, String[] requiredScopes, Options options) throws WebApplicationException + { + return validate(accessToken, requiredScopes, null, null, options); } /** - * Validate an access token. This method is an alias of the - * {@link #validate(Params)} method. + * Validate an access token. This method is an alias of + * {@link #validate(String, String[], String, String, Options) validate}{@code + * (accessToken, requiredScopes, requiredSubject, clientCertificate, null)}. + * + * @param accessToken + * An access token to validate. + * + * @param requiredScopes + * Scopes that must be associated with the access token. + * {@code null} is okay. + * + * @param requiredSubject + * Subject (= user's unique identifier) that must be associated + * with the access token. {@code null} is okay. + * + * @param clientCertificate + * TLS Certificate of the client presented during a call to + * the resource server, used with TLS-bound access tokens. + * Can be {@code null} if no certificate is presented. + * + * @return + * Information about the access token. + * + * @throws WebApplicationException + * The access token is invalid. To be concrete, one or more of + * the following conditions meet. + *
    + *
  1. The access token does not exist. + *
  2. The access token has expired. + *
  3. The access token does not cover the required scopes. + *
  4. The access token is not associated with the required subject. + *
  5. The access token is bound to a client certificate, but the + * presented one does not match. + *
+ */ + public AccessTokenInfo validate( + String accessToken, String[] requiredScopes, + String requiredSubject, String clientCertificate) throws WebApplicationException + { + return validate(accessToken, requiredScopes, requiredSubject, clientCertificate, null); + } + + + /** + * Validate an access token. This method is an alias of the {@link #validate(Params)} + * method. * *

* When the given access token is not valid, this method throws a @@ -439,6 +554,9 @@ public AccessTokenInfo validate( * the resource server, used with TLS-bound access tokens. * Can be {@code null} if no certificate is presented. * + * @param options + * The request options for the {@code /api/auth/introspection} API. + * * @return * Information about the access token. * @@ -453,16 +571,20 @@ public AccessTokenInfo validate( *
  • The access token is bound to a client certificate, but the * presented one does not match. * + * + * @since 2.27 */ public AccessTokenInfo validate( String accessToken, String[] requiredScopes, - String requiredSubject, String clientCertificate) throws WebApplicationException + String requiredSubject, String clientCertificate, Options options) + throws WebApplicationException { Params params = new Params() .setAccessToken(accessToken) .setRequiredScopes(requiredScopes) .setRequiredSubject(requiredSubject) .setClientCertificate(clientCertificate) + .setOptions(options) ; return validate(params); @@ -508,7 +630,8 @@ public AccessTokenInfo validate(Params params) throws WebApplicationException /** - * Validate an access token. + * Validate an access token. This method is an alias of the + * {@link #validate(IntrospectionRequest, Options) validate}{@code (request, null)}. * * @param request * The request parameters to Authlete's {@code /auth/introspection} API. @@ -525,10 +648,37 @@ public AccessTokenInfo validate(Params params) throws WebApplicationException * @since 2.66 */ public IntrospectionResponse validate(IntrospectionRequest request) throws WebApplicationException + { + return validate(request, null); + } + + + /** + * Validate an access token. + * + * @param request + * The request parameters to Authlete's {@code /auth/introspection} API. + * + * @param options + * The request options for the {@code /api/auth/introspection} API. + * + * @return + * The response from the Authlete's {@code /auth/introspection} API. + * + * @throws WebApplicationException + * The access token is invalid or something unexpected happened. + * This exception is raised when the {@code action} response parameter + * in the response from the {@code /auth/introspection} API is not + * {@link IntrospectionResponse.Action#OK OK}. + * + * @since 2.82 + */ + public IntrospectionResponse validate( + IntrospectionRequest request, Options options) throws WebApplicationException { try { - return process(request); + return process(request, options); } catch (WebApplicationException e) { @@ -552,7 +702,8 @@ private AccessTokenInfo process(Params params) throws WebApplicationException params.getClientCertificate(), params.getDpop(), params.getHtm(), - params.getHtu() + params.getHtu(), + params.getOptions() ); // Handle the response from the /auth/introspection API. @@ -563,10 +714,11 @@ private AccessTokenInfo process(Params params) throws WebApplicationException } - private IntrospectionResponse process(IntrospectionRequest request) throws WebApplicationException + private IntrospectionResponse process( + IntrospectionRequest request, Options options) throws WebApplicationException { // Call Authlete's /api/auth/introspection API. - IntrospectionResponse response = getApiCaller().callIntrospection(request); + IntrospectionResponse response = getApiCaller().callIntrospection(request, options); // Handle the response from the /auth/introspection API. handleIntrospectionResponse(response); diff --git a/src/main/java/com/authlete/jakarta/AuthleteApiCaller.java b/src/main/java/com/authlete/jakarta/AuthleteApiCaller.java index e387ec0..247f3be 100644 --- a/src/main/java/com/authlete/jakarta/AuthleteApiCaller.java +++ b/src/main/java/com/authlete/jakarta/AuthleteApiCaller.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2023 Authlete, Inc. + * Copyright (C) 2015-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ import jakarta.ws.rs.core.Response.Status; import com.authlete.common.api.AuthleteApi; import com.authlete.common.api.AuthleteApiException; +import com.authlete.common.api.Options; import com.authlete.common.dto.AuthorizationFailRequest; import com.authlete.common.dto.AuthorizationFailResponse; import com.authlete.common.dto.AuthorizationIssueRequest; @@ -170,18 +171,18 @@ private InternalServerErrorException internalServerError(String message, Throwab /** * Call Authlete's {@code /api/auth/authorization} API. */ - public AuthorizationResponse callAuthorization(MultivaluedMap parameters) + public AuthorizationResponse callAuthorization(MultivaluedMap parameters, Options options) { String params = URLCoder.formUrlEncode(parameters); - return callAuthorization(params); + return callAuthorization(params, options); } /** * Call Authlete's {@code /api/auth/authorization} API. */ - private AuthorizationResponse callAuthorization(String parameters) + private AuthorizationResponse callAuthorization(String parameters, Options options) { if (parameters == null) { @@ -198,7 +199,7 @@ private AuthorizationResponse callAuthorization(String parameters) try { // Call Authlete's /api/auth/authorization API. - return mApi.authorization(request); + return mApi.authorization(request, options); } catch (AuthleteApiException e) { @@ -211,7 +212,8 @@ private AuthorizationResponse callAuthorization(String parameters) /** * Call Authlete's {@code /api/auth/authorization/fail} API. */ - private AuthorizationFailResponse callAuthorizationFail(String ticket, AuthorizationFailRequest.Reason reason) + private AuthorizationFailResponse callAuthorizationFail( + String ticket, AuthorizationFailRequest.Reason reason, Options options) { // Create a request for /api/auth/authorization/fail API. AuthorizationFailRequest request = new AuthorizationFailRequest() @@ -221,7 +223,7 @@ private AuthorizationFailResponse callAuthorizationFail(String ticket, Authoriza try { // Call Authlete's /api/auth/authorization/fail API. - return mApi.authorizationFail(request); + return mApi.authorizationFail(request, options); } catch (AuthleteApiException e) { @@ -235,10 +237,11 @@ private AuthorizationFailResponse callAuthorizationFail(String ticket, Authoriza * Create a response that describes the failure. This method * calls Authlete's {@code /api/auth/authorization/fail} API. */ - private Response createAuthorizationFailResponse(String ticket, AuthorizationFailRequest.Reason reason) + private Response createAuthorizationFailResponse( + String ticket, AuthorizationFailRequest.Reason reason, Options options) { // Call Authlete's /api/auth/authorization/fail API. - AuthorizationFailResponse response = callAuthorizationFail(ticket, reason); + AuthorizationFailResponse response = callAuthorizationFail(ticket, reason, options); // 'action' in the response denotes the next action which // this service implementation should take. @@ -278,11 +281,12 @@ private Response createAuthorizationFailResponse(String ticket, AuthorizationFai * Create an exception that describes the failure. This method * calls Authlete's {@code /api/auth/authorization/fail} API. */ - public WebApplicationException authorizationFail(String ticket, AuthorizationFailRequest.Reason reason) + public WebApplicationException authorizationFail( + String ticket, AuthorizationFailRequest.Reason reason, Options options) { // Create a response to the client application with the help of // Authlete's /api/auth/authorization/fail API. - Response response = createAuthorizationFailResponse(ticket, reason); + Response response = createAuthorizationFailResponse(ticket, reason, options); // Create an exception containing the response. return new WebApplicationException(response); @@ -296,7 +300,7 @@ private AuthorizationIssueResponse callAuthorizationIssue( String ticket, String subject, long authTime, String acr, Map claims, Property[] properties, String[] scopes, String sub, Map claimsForTx, - List> verifiedClaimsForTx) + List> verifiedClaimsForTx, Options options) { // Create a request for /api/auth/authorization/issue API. AuthorizationIssueRequest request = new AuthorizationIssueRequest() @@ -319,7 +323,7 @@ private AuthorizationIssueResponse callAuthorizationIssue( try { // Call Authlete's /api/auth/authorization/issue API. - return mApi.authorizationIssue(request); + return mApi.authorizationIssue(request, options); } catch (AuthleteApiException e) { @@ -335,9 +339,11 @@ private AuthorizationIssueResponse callAuthorizationIssue( */ public Response authorizationIssue( String ticket, String subject, long authTime, String acr, - Map claims, Property[] properties, String[] scopes) + Map claims, Property[] properties, String[] scopes, + Options options) { - return authorizationIssue(ticket, subject, authTime, acr, claims, properties, scopes, null); + return authorizationIssue( + ticket, subject, authTime, acr, claims, properties, scopes, null, options); } @@ -347,10 +353,10 @@ public Response authorizationIssue( */ public Response authorizationIssue( String ticket, String subject, long authTime, String acr, - Map claims, Property[] properties, String[] scopes, String sub) + Map claims, Property[] properties, String[] scopes, String sub, Options options) { return authorizationIssue( - ticket, subject, authTime, acr, claims, properties, scopes, sub, null, null); + ticket, subject, authTime, acr, claims, properties, scopes, sub, null, null, options); } @@ -362,12 +368,12 @@ public Response authorizationIssue( String ticket, String subject, long authTime, String acr, Map claims, Property[] properties, String[] scopes, String sub, Map claimsForTx, - List> verifiedClaimsForTx) + List> verifiedClaimsForTx, Options options) { // Call Authlete's /api/auth/authorization/issue API. AuthorizationIssueResponse response = callAuthorizationIssue(ticket, subject, authTime, acr, claims, - properties, scopes, sub, claimsForTx, verifiedClaimsForTx); + properties, scopes, sub, claimsForTx, verifiedClaimsForTx, options); // 'action' in the response denotes the next action which // this service implementation should take. @@ -409,13 +415,13 @@ public Response authorizationIssue( public TokenResponse callToken( MultivaluedMap parameters, String clientId, String clientSecret, Property[] properties, String clientCertificate, String[] clientCertificatePath, - String dpop, String htm, String htu) + String dpop, String htm, String htu, Options options) { String params = URLCoder.formUrlEncode(parameters); return callToken(params, clientId, clientSecret, properties, clientCertificate, clientCertificatePath, - dpop, htm, htu); + dpop, htm, htu, options); } @@ -425,7 +431,7 @@ public TokenResponse callToken( public TokenResponse callToken( String parameters, String clientId, String clientSecret, Property[] properties, String clientCertificate, String[] clientCertificatePath, - String dpop, String htm, String htu) + String dpop, String htm, String htu, Options options) { if (parameters == null) { @@ -451,7 +457,7 @@ public TokenResponse callToken( try { // Call Authlete's /api/auth/token API. - return mApi.token(request); + return mApi.token(request, options); } catch (AuthleteApiException e) { @@ -464,7 +470,8 @@ public TokenResponse callToken( /** * Call Authlete's {@code /api/auth/token/fail} API. */ - private TokenFailResponse callTokenFail(String ticket, TokenFailRequest.Reason reason) + private TokenFailResponse callTokenFail( + String ticket, TokenFailRequest.Reason reason, Options options) { // Create a request for /api/auth/token/fail API. TokenFailRequest request = new TokenFailRequest() @@ -474,7 +481,7 @@ private TokenFailResponse callTokenFail(String ticket, TokenFailRequest.Reason r try { // Call Authlete's /api/auth/token/fail API. - return mApi.tokenFail(request); + return mApi.tokenFail(request, options); } catch (AuthleteApiException e) { @@ -490,10 +497,10 @@ private TokenFailResponse callTokenFail(String ticket, TokenFailRequest.Reason r */ private Response createTokenFailResponse( String ticket, TokenFailRequest.Reason reason, - Map headers) + Map headers, Options options) { // Call Authlete's /api/auth/token/fail API. - TokenFailResponse response = callTokenFail(ticket, reason); + TokenFailResponse response = callTokenFail(ticket, reason, options); // 'action' in the response denotes the next action which // this service implementation should take. @@ -526,11 +533,11 @@ private Response createTokenFailResponse( */ public WebApplicationException tokenFail( String ticket, TokenFailRequest.Reason reason, - Map headers) + Map headers, Options options) { // Create a response to the client application with the help of // Authlete's /api/auth/token/fail API. - Response response = createTokenFailResponse(ticket, reason, headers); + Response response = createTokenFailResponse(ticket, reason, headers, options); // Create an exception containing the response. return new WebApplicationException(response); @@ -541,7 +548,7 @@ public WebApplicationException tokenFail( * Call Authlete's {@code /api/auth/token/issue} API. */ private TokenIssueResponse callTokenIssue( - String ticket, String subject, Property[] properties) + String ticket, String subject, Property[] properties, Options options) { // Create a request for Authlete's /api/auth/token/issue API. TokenIssueRequest request = new TokenIssueRequest() @@ -569,10 +576,10 @@ private TokenIssueResponse callTokenIssue( */ public Response tokenIssue( String ticket, String subject, Property[] properties, - Map headers) + Map headers, Options options) { // Call Authlete's /api/auth/token/issue API. - TokenIssueResponse response = callTokenIssue(ticket, subject, properties); + TokenIssueResponse response = callTokenIssue(ticket, subject, properties, options); // 'action' in the response denotes the next action which // this service implementation should take. @@ -602,12 +609,12 @@ public Response tokenIssue( /** * Call Authlete's {@code /api/service/configuration} API. */ - public String callServiceConfiguration(boolean pretty) + public String callServiceConfiguration(boolean pretty, Options options) { try { // Call Authlete's /api/service/configuration API. - return mApi.getServiceConfiguration(pretty); + return mApi.getServiceConfiguration(pretty, options); } catch (AuthleteApiException e) { @@ -620,12 +627,12 @@ public String callServiceConfiguration(boolean pretty) /** * Call Authlete's {@code /api/service/configuration} API. */ - public String callServiceConfiguration(ServiceConfigurationRequest request) + public String callServiceConfiguration(ServiceConfigurationRequest request, Options options) { try { // Call Authlete's /api/service/configuration API. - return mApi.getServiceConfiguration(request); + return mApi.getServiceConfiguration(request, options); } catch (AuthleteApiException e) { @@ -640,12 +647,12 @@ public String callServiceConfiguration(ServiceConfigurationRequest request) * {@code /api/service/jwks/get} API. */ public Response serviceJwksGet( - boolean pretty, boolean includePrivateKeys) throws AuthleteApiException + boolean pretty, boolean includePrivateKeys, Options options) throws AuthleteApiException { try { // Call Authlete's /api/service/jwks/get API. - String jwks = mApi.getServiceJwks(pretty, includePrivateKeys); + String jwks = mApi.getServiceJwks(pretty, includePrivateKeys, options); if (jwks == null || jwks.length() == 0) { @@ -695,18 +702,20 @@ private static String getFirst(Map> map, String key) /** * Call Authlete's {@code /api/auth/revocation} API. */ - public RevocationResponse callRevocation(MultivaluedMap parameters, String clientId, String clientSecret) + public RevocationResponse callRevocation( + MultivaluedMap parameters, String clientId, String clientSecret, Options options) { String params = URLCoder.formUrlEncode(parameters); - return callRevocation(params, clientId, clientSecret); + return callRevocation(params, clientId, clientSecret, options); } /** * Call Authlete's {@code /api/auth/revocation} API. */ - private RevocationResponse callRevocation(String parameters, String clientId, String clientSecret) + private RevocationResponse callRevocation( + String parameters, String clientId, String clientSecret, Options options) { if (parameters == null) { @@ -725,7 +734,7 @@ private RevocationResponse callRevocation(String parameters, String clientId, St try { // Call Authlete's /api/auth/revocation API. - return mApi.revocation(request); + return mApi.revocation(request, options); } catch (AuthleteApiException e) { @@ -739,7 +748,7 @@ private RevocationResponse callRevocation(String parameters, String clientId, St * Call Authlete's {@code /api/auth/userinfo} API. */ public UserInfoResponse callUserInfo( - String accessToken, String clientCertificate, String dpop, String htm, String htu) + String accessToken, String clientCertificate, String dpop, String htm, String htu, Options options) { // Create a request for Authlete's /api/auth/userinfo API. UserInfoRequest request = new UserInfoRequest() @@ -753,7 +762,7 @@ public UserInfoResponse callUserInfo( try { // Call Authlete's /api/auth/userinfo API. - return mApi.userinfo(request); + return mApi.userinfo(request, options); } catch (AuthleteApiException e) { @@ -768,7 +777,7 @@ public UserInfoResponse callUserInfo( */ private UserInfoIssueResponse callUserInfoIssue(String accessToken, Map claims, Map claimsForTx, - List> verifiedClaimsForTx) + List> verifiedClaimsForTx, Options options) { // Create a request for /api/auth/userinfo/issue API. UserInfoIssueRequest request = new UserInfoIssueRequest() @@ -792,7 +801,7 @@ private UserInfoIssueResponse callUserInfoIssue(String accessToken, try { // Call Authlete's /api/auth/userinfo/issue API. - return mApi.userinfoIssue(request); + return mApi.userinfoIssue(request, options); } catch (AuthleteApiException e) { @@ -808,11 +817,11 @@ private UserInfoIssueResponse callUserInfoIssue(String accessToken, public Response userInfoIssue(String accessToken, Map claims, Map claimsForTx, List> verifiedClaimsForTx, - Map headers) + Map headers, Options options) { // Call Authlete's /api/auth/userinfo/issue API. UserInfoIssueResponse response = callUserInfoIssue( - accessToken, claims, claimsForTx, verifiedClaimsForTx); + accessToken, claims, claimsForTx, verifiedClaimsForTx, options); // 'action' in the response denotes the next action which // this service implementation should take. @@ -861,7 +870,7 @@ public Response userInfoIssue(String accessToken, */ public IntrospectionResponse callIntrospection( String accessToken, String[] scopes, String subject, String clientCertificate, - String dpop, String htm, String htu) + String dpop, String htm, String htu, Options options) { // Create a request for /api/auth/introspection API. IntrospectionRequest request = new IntrospectionRequest() @@ -874,16 +883,16 @@ public IntrospectionResponse callIntrospection( .setHtu(htu) ; - return callIntrospection(request); + return callIntrospection(request, options); } - public IntrospectionResponse callIntrospection(IntrospectionRequest request) + public IntrospectionResponse callIntrospection(IntrospectionRequest request, Options options) { try { // Call Authlete's /api/auth/introspection API. - return mApi.introspection(request); + return mApi.introspection(request, options); } catch (AuthleteApiException e) { @@ -899,13 +908,13 @@ public IntrospectionResponse callIntrospection(IntrospectionRequest request) public StandardIntrospectionResponse callStandardIntrospection( MultivaluedMap parameters, boolean withHiddenProperties, String httpAcceptHeader, URI rsUri, JWSAlg introspectionSignAlg, JWEAlg introspectionEncAlg, JWEEnc introspectionEncEnc, - String sharedKeyForSign, String sharedKeyForEncryption, String publicKeyForEncryption) + String sharedKeyForSign, String sharedKeyForEncryption, String publicKeyForEncryption, Options options) { String params = URLCoder.formUrlEncode(parameters); return callStandardIntrospection( params, withHiddenProperties, httpAcceptHeader, rsUri, introspectionSignAlg, introspectionEncAlg, - introspectionEncEnc, sharedKeyForSign, sharedKeyForEncryption, publicKeyForEncryption); + introspectionEncEnc, sharedKeyForSign, sharedKeyForEncryption, publicKeyForEncryption, options); } @@ -915,7 +924,8 @@ public StandardIntrospectionResponse callStandardIntrospection( private StandardIntrospectionResponse callStandardIntrospection( String parameters, boolean withHiddenProperties, String httpAcceptHeader, URI rsUri, JWSAlg introspectionSignAlg, JWEAlg introspectionEncAlg, JWEEnc introspectionEncEnc, - String sharedKeyForSign, String sharedKeyForEncryption, String publicKeyForEncryption) + String sharedKeyForSign, String sharedKeyForEncryption, String publicKeyForEncryption, + Options options) { if (parameters == null) { @@ -941,7 +951,7 @@ private StandardIntrospectionResponse callStandardIntrospection( try { // Call Authlete's /api/auth/introspection/standard API. - return mApi.standardIntrospection(request); + return mApi.standardIntrospection(request, options); } catch (AuthleteApiException e) { @@ -956,11 +966,12 @@ private StandardIntrospectionResponse callStandardIntrospection( */ public BackchannelAuthenticationResponse callBackchannelAuthentication( MultivaluedMap parameters, String clientId, String clientSecret, - String clientCertificate, String[] clientCertificatePath) + String clientCertificate, String[] clientCertificatePath, Options options) { String params = URLCoder.formUrlEncode(parameters); - return callBackchannelAuthentication(params, clientId, clientSecret, clientCertificate, clientCertificatePath); + return callBackchannelAuthentication( + params, clientId, clientSecret, clientCertificate, clientCertificatePath, options); } @@ -969,7 +980,7 @@ public BackchannelAuthenticationResponse callBackchannelAuthentication( */ private BackchannelAuthenticationResponse callBackchannelAuthentication( String parameters, String clientId, String clientSecret, - String clientCertificate, String[] clientCertificatePath) + String clientCertificate, String[] clientCertificatePath, Options options) { if (parameters == null) { @@ -991,7 +1002,7 @@ private BackchannelAuthenticationResponse callBackchannelAuthentication( try { // Call Authlete's /api/backchannel/authentication API. - return mApi.backchannelAuthentication(request); + return mApi.backchannelAuthentication(request, options); } catch (AuthleteApiException e) { @@ -1004,7 +1015,8 @@ private BackchannelAuthenticationResponse callBackchannelAuthentication( /** * Call Authlete's {@code /api/backchannel/authentication/fail} API. */ - private BackchannelAuthenticationFailResponse callBackchannelAuthenticationFail(String ticket, BackchannelAuthenticationFailRequest.Reason reason) + private BackchannelAuthenticationFailResponse callBackchannelAuthenticationFail( + String ticket, BackchannelAuthenticationFailRequest.Reason reason, Options options) { // Create a request for /api/backchannel/authentication/fail API. BackchannelAuthenticationFailRequest request = new BackchannelAuthenticationFailRequest() @@ -1015,7 +1027,7 @@ private BackchannelAuthenticationFailResponse callBackchannelAuthenticationFail( try { // Call Authlete's /api/backchannel/authentication/fail API. - return mApi.backchannelAuthenticationFail(request); + return mApi.backchannelAuthenticationFail(request, options); } catch (AuthleteApiException e) { @@ -1029,10 +1041,11 @@ private BackchannelAuthenticationFailResponse callBackchannelAuthenticationFail( * Create a response that describes the failure. This method * calls Authlete's {@code /api/backchannel/authentication/fail} API. */ - private Response createBackchannelAuthenticationFailResponse(String ticket, BackchannelAuthenticationFailRequest.Reason reason) + private Response createBackchannelAuthenticationFailResponse( + String ticket, BackchannelAuthenticationFailRequest.Reason reason, Options options) { // Call Authlete's /api/backchannel/authentication/fail API. - BackchannelAuthenticationFailResponse response = callBackchannelAuthenticationFail(ticket, reason); + BackchannelAuthenticationFailResponse response = callBackchannelAuthenticationFail(ticket, reason, options); // 'action' in the response denotes the next action which // this service implementation should take. @@ -1068,11 +1081,12 @@ private Response createBackchannelAuthenticationFailResponse(String ticket, Back * Create an exception that describes the failure. This method * calls Authlete's {@code /api/backchannel/authentication/fail} API. */ - public WebApplicationException backchannelAuthenticationFail(String ticket, BackchannelAuthenticationFailRequest.Reason reason) + public WebApplicationException backchannelAuthenticationFail( + String ticket, BackchannelAuthenticationFailRequest.Reason reason, Options options) { // Create a response to the client application with the help of // Authlete's /api/backchannel/authentication/fail API. - Response response = createBackchannelAuthenticationFailResponse(ticket, reason); + Response response = createBackchannelAuthenticationFailResponse(ticket, reason, options); // Create an exception containing the response. return new WebApplicationException(response); @@ -1082,7 +1096,8 @@ public WebApplicationException backchannelAuthenticationFail(String ticket, Back /** * Call Authlete's {@code /api/backchannel/authentication/issue} API. */ - public BackchannelAuthenticationIssueResponse callBackchannelAuthenticationIssue(String ticket) + public BackchannelAuthenticationIssueResponse callBackchannelAuthenticationIssue( + String ticket, Options options) { // Create a request for /api/backchannel/authentication/issue API. BackchannelAuthenticationIssueRequest request = new BackchannelAuthenticationIssueRequest() @@ -1092,7 +1107,7 @@ public BackchannelAuthenticationIssueResponse callBackchannelAuthenticationIssue try { // Call Authlete's /api/backchannel/authentication/issue API. - return mApi.backchannelAuthenticationIssue(request); + return mApi.backchannelAuthenticationIssue(request, options); } catch (AuthleteApiException e) { @@ -1108,7 +1123,7 @@ public BackchannelAuthenticationIssueResponse callBackchannelAuthenticationIssue public BackchannelAuthenticationCompleteResponse callBackchannelAuthenticationComplete( String ticket, String subject, Result result, long authTime, String acr, Map claims, Property[] properties, String[] scopes, - String errorDescription, URI errorUri) + String errorDescription, URI errorUri, Options options) { // Create a request for /api/backchannel/authentication/complete API. BackchannelAuthenticationCompleteRequest request = new BackchannelAuthenticationCompleteRequest() @@ -1131,7 +1146,7 @@ public BackchannelAuthenticationCompleteResponse callBackchannelAuthenticationCo try { // Call Authlete's /api/backchannel/authentication/complete API. - return mApi.backchannelAuthenticationComplete(request); + return mApi.backchannelAuthenticationComplete(request, options); } catch (AuthleteApiException e) { @@ -1145,9 +1160,9 @@ public BackchannelAuthenticationCompleteResponse callBackchannelAuthenticationCo * Call Authlete's {@code /api/client/registration} API. */ public ClientRegistrationResponse callClientRegistration( - String json) + String json, Options options) { - return callClientRegistration(json, null); + return callClientRegistration(json, null, options); } @@ -1156,7 +1171,7 @@ public ClientRegistrationResponse callClientRegistration( * with an initial access token. */ public ClientRegistrationResponse callClientRegistration( - String json, String initialAccessToken) + String json, String initialAccessToken, Options options) { ClientRegistrationRequest request = new ClientRegistrationRequest() .setJson(json) @@ -1165,7 +1180,7 @@ public ClientRegistrationResponse callClientRegistration( try { - return mApi.dynamicClientRegister(request); + return mApi.dynamicClientRegister(request, options); } catch (AuthleteApiException e) { @@ -1178,7 +1193,7 @@ public ClientRegistrationResponse callClientRegistration( * Call Authlete's {@code /api/client/registration/get} API. */ public ClientRegistrationResponse callClientRegistrationGet( - String clientId, String registrationAccessToken) + String clientId, String registrationAccessToken, Options options) { ClientRegistrationRequest request = new ClientRegistrationRequest() .setClientId(clientId) @@ -1186,7 +1201,7 @@ public ClientRegistrationResponse callClientRegistrationGet( try { - return mApi.dynamicClientGet(request); + return mApi.dynamicClientGet(request, options); } catch (AuthleteApiException e) { @@ -1199,7 +1214,7 @@ public ClientRegistrationResponse callClientRegistrationGet( * Call Authlete's {@code /api/client/registration/update} API. */ public ClientRegistrationResponse callClientRegistrationUpdate( - String clientId, String json, String registrationAccessToken) + String clientId, String json, String registrationAccessToken, Options options) { ClientRegistrationRequest request = new ClientRegistrationRequest() .setClientId(clientId) @@ -1208,7 +1223,7 @@ public ClientRegistrationResponse callClientRegistrationUpdate( try { - return mApi.dynamicClientUpdate(request); + return mApi.dynamicClientUpdate(request, options); } catch (AuthleteApiException e) { @@ -1221,7 +1236,7 @@ public ClientRegistrationResponse callClientRegistrationUpdate( * Call Authlete's {@code /api/client/registration/delete} API. */ public ClientRegistrationResponse callClientRegistrationDelete( - String clientId, String registrationAccessToken) + String clientId, String registrationAccessToken, Options options) { ClientRegistrationRequest request = new ClientRegistrationRequest() .setClientId(clientId) @@ -1229,7 +1244,7 @@ public ClientRegistrationResponse callClientRegistrationDelete( try { - return mApi.dynamicClientDelete(request); + return mApi.dynamicClientDelete(request, options); } catch (AuthleteApiException e) { @@ -1244,13 +1259,13 @@ public ClientRegistrationResponse callClientRegistrationDelete( public DeviceAuthorizationResponse callDeviceAuthorization( MultivaluedMap parameters, String clientId, String clientSecret, - String clientCertificate, String[] clientCertificatePath) + String clientCertificate, String[] clientCertificatePath, Options options) { String params = URLCoder.formUrlEncode(parameters); return callDeviceAuthorization( params, clientId, clientSecret, - clientCertificate, clientCertificatePath); + clientCertificate, clientCertificatePath, options); } @@ -1259,7 +1274,7 @@ public DeviceAuthorizationResponse callDeviceAuthorization( */ private DeviceAuthorizationResponse callDeviceAuthorization( String parameters, String clientId, String clientSecret, - String clientCertificate, String[] clientCertificatePath) + String clientCertificate, String[] clientCertificatePath, Options options) { if (parameters == null) { @@ -1281,7 +1296,7 @@ private DeviceAuthorizationResponse callDeviceAuthorization( try { // Call Authlete's /api/device/authorization API. - return mApi.deviceAuthorization(request); + return mApi.deviceAuthorization(request, options); } catch (AuthleteApiException e) { @@ -1297,7 +1312,7 @@ private DeviceAuthorizationResponse callDeviceAuthorization( public DeviceCompleteResponse callDeviceComplete( String userCode, String subject, DeviceCompleteRequest.Result result, long authTime, String acr, Map claims, Property[] properties, - String[] scopes, String errorDescription, URI errorUri) + String[] scopes, String errorDescription, URI errorUri, Options options) { // Create a request for /api/device/complete API. DeviceCompleteRequest request = new DeviceCompleteRequest() @@ -1320,7 +1335,7 @@ public DeviceCompleteResponse callDeviceComplete( try { // Call Authlete's /api/device/complete API. - return mApi.deviceComplete(request); + return mApi.deviceComplete(request, options); } catch (AuthleteApiException e) { @@ -1333,7 +1348,7 @@ public DeviceCompleteResponse callDeviceComplete( /** * Call Authlete's {@code /api/device/verification} API. */ - public DeviceVerificationResponse callDeviceVerification(String userCode) + public DeviceVerificationResponse callDeviceVerification(String userCode, Options options) { // Create a request for /api/device/verification API. DeviceVerificationRequest request = new DeviceVerificationRequest() @@ -1343,7 +1358,7 @@ public DeviceVerificationResponse callDeviceVerification(String userCode) try { // Call Authlete's /api/device/verification API. - return mApi.deviceVerification(request); + return mApi.deviceVerification(request, options); } catch (AuthleteApiException e) { @@ -1359,13 +1374,13 @@ public DeviceVerificationResponse callDeviceVerification(String userCode) public PushedAuthReqResponse callPushedAuthReq( MultivaluedMap parameters, String clientId, String clientSecret, String clientCertificate, String[] clientCertificatePath, - String dpop, String htm, String htu) + String dpop, String htm, String htu, Options options) { String params = URLCoder.formUrlEncode(parameters); return callPushedAuthReq( params, clientId, clientSecret, clientCertificate, clientCertificatePath, - dpop, htm, htu); + dpop, htm, htu, options); } @@ -1375,7 +1390,7 @@ public PushedAuthReqResponse callPushedAuthReq( public PushedAuthReqResponse callPushedAuthReq( String parameters, String clientId, String clientSecret, String clientCertificate, String[] clientCertificatePath, - String dpop, String htm, String htu) + String dpop, String htm, String htu, Options options) { PushedAuthReqRequest request = new PushedAuthReqRequest() .setParameters(parameters) @@ -1390,7 +1405,7 @@ public PushedAuthReqResponse callPushedAuthReq( try { - return mApi.pushAuthorizationRequest(request); + return mApi.pushAuthorizationRequest(request, options); } catch (AuthleteApiException e) { @@ -1403,11 +1418,11 @@ public PushedAuthReqResponse callPushedAuthReq( /** * Call Authlete's {@code /api/gm} API. */ - public GMResponse callGm(GMRequest request) + public GMResponse callGm(GMRequest request, Options options) { try { - return mApi.gm(request); + return mApi.gm(request, options); } catch (AuthleteApiException e) { @@ -1421,11 +1436,11 @@ public GMResponse callGm(GMRequest request) * Call Authlete's {@code /api/federation/configuration} API. */ public FederationConfigurationResponse - callFederationConfiguration(FederationConfigurationRequest request) + callFederationConfiguration(FederationConfigurationRequest request, Options options) { try { - return mApi.federationConfiguration(request); + return mApi.federationConfiguration(request, options); } catch (AuthleteApiException e) { @@ -1439,11 +1454,11 @@ public GMResponse callGm(GMRequest request) * Call Authlete's {@code /api/federation/registration} API. */ public FederationRegistrationResponse - callFederationRegistration(FederationRegistrationRequest request) + callFederationRegistration(FederationRegistrationRequest request, Options options) { try { - return mApi.federationRegistration(request); + return mApi.federationRegistration(request, options); } catch (AuthleteApiException e) { @@ -1457,11 +1472,11 @@ public GMResponse callGm(GMRequest request) * Call Authlete's {@code /vci/metadata} API. */ public CredentialIssuerMetadataResponse - callCredentialIssuerMetadata(CredentialIssuerMetadataRequest request) + callCredentialIssuerMetadata(CredentialIssuerMetadataRequest request, Options options) { try { - return mApi.credentialIssuerMetadata(request); + return mApi.credentialIssuerMetadata(request, options); } catch (AuthleteApiException e) { @@ -1475,11 +1490,11 @@ public GMResponse callGm(GMRequest request) * Call Authlete's {@code /vci/jwtissuer} API. */ public CredentialJwtIssuerMetadataResponse - callCredentialJwtIssuerMetadata(CredentialJwtIssuerMetadataRequest request) + callCredentialJwtIssuerMetadata(CredentialJwtIssuerMetadataRequest request, Options options) { try { - return mApi.credentialJwtIssuerMetadata(request); + return mApi.credentialJwtIssuerMetadata(request, options); } catch (AuthleteApiException e) { @@ -1492,11 +1507,12 @@ public GMResponse callGm(GMRequest request) /** * Call Authlete's {@code /vci/offer/info} API. */ - public CredentialOfferInfoResponse callCredentialOfferInfo(CredentialOfferInfoRequest request) + public CredentialOfferInfoResponse callCredentialOfferInfo( + CredentialOfferInfoRequest request, Options options) { try { - return mApi.credentialOfferInfo(request); + return mApi.credentialOfferInfo(request, options); } catch (AuthleteApiException e) { diff --git a/src/main/java/com/authlete/jakarta/AuthorizationDecisionHandler.java b/src/main/java/com/authlete/jakarta/AuthorizationDecisionHandler.java index 15b3cb6..810f75d 100644 --- a/src/main/java/com/authlete/jakarta/AuthorizationDecisionHandler.java +++ b/src/main/java/com/authlete/jakarta/AuthorizationDecisionHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2022 Authlete, Inc. + * Copyright (C) 2015-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.assurance.VerifiedClaims; import com.authlete.common.assurance.constraint.VerifiedClaimsConstraint; import com.authlete.common.assurance.constraint.VerifiedClaimsContainerConstraint; @@ -59,7 +60,7 @@ public class AuthorizationDecisionHandler extends BaseHandler */ public static class Params implements Serializable { - private static final long serialVersionUID = 3L; + private static final long serialVersionUID = 4L; private String ticket; @@ -69,6 +70,9 @@ public static class Params implements Serializable private String[] requestedClaimsForTx; private StringArray[] requestedVerifiedClaimsForTx; private boolean oldIdaFormatUsed; + private Options authzOptions; + private Options authzIssueOptions; + private Options authzFailOptions; /** @@ -429,6 +433,105 @@ public Params setOldIdaFormatUsed(boolean used) } + /** + * Get the request options for the {@code /api/auth/authorization} API. + * + * @return + * The request options for the {@code /api/auth/authorization} API. + * + * @since 2.82 + */ + public Options getAuthzOptions() + { + return authzOptions; + } + + + /** + * Set the request options for the {@code /api/auth/authorization} API. + * + * @param options + * The request options for the {@code /api/auth/authorization} API. + * + * @return + * {@code this} object. + * + * @since 2.82 + */ + public Params setAuthzOptions(Options options) + { + authzOptions = options; + + return this; + } + + + /** + * Get the request options for the {@code /api/auth/authorization/issue} API. + * + * @return + * The request options for the {@code /api/auth/authorization/issue} API. + * + * @since 2.82 + */ + public Options getAuthzIssueOptions() + { + return authzIssueOptions; + } + + + /** + * Set the request options for the {@code /api/auth/authorization/issue} API. + * + * @param options + * The request options for the {@code /api/auth/authorization/issue} API. + * + * @return + * {@code this} object. + * + * @since 2.82 + */ + public Params setAuthzIssueOptions(Options options) + { + authzIssueOptions = options; + + return this; + } + + + /** + * Get the request options for the {@code /api/auth/authorization/fail} API. + * + * @return + * The request options for the {@code /api/auth/authorization/fail} API. + * + * @since 2.82 + */ + public Options getAuthzFailOptions() + { + return authzFailOptions; + } + + + /** + * Set the request options for the {@code /api/auth/authorization/fail} API. + * + * @param options + * The request options for the {@code /api/auth/authorization/fail} API. + * + * @return + * {@code this} object. + * + * @since 2.82 + */ + public Params setAuthzFailOptions(Options options) + { + authzFailOptions = options; + + return this; + } + + /** * Create a {@link Params} instance from an instance of * {@link AuthorizationResponse}. @@ -479,7 +582,9 @@ public AuthorizationDecisionHandler(AuthleteApi api, AuthorizationDecisionHandle /** - * Handle an end-user's decision on an authorization request. + * Handle an end-user's decision on an authorization request. This method is + * an alias of {@link #handle(String, String[], String[], Options, Options) + * handle}{@code (ticket, claimNames, claimLocales, null, null)}. * * @param ticket * A ticket that was issued by Authlete's {@code /api/auth/authorization} API. @@ -500,11 +605,51 @@ public AuthorizationDecisionHandler(AuthleteApi api, AuthorizationDecisionHandle * An error occurred. */ public Response handle(String ticket, String[] claimNames, String[] claimLocales) throws WebApplicationException + { + return handle(ticket, claimNames, claimLocales, null, null); + } + + + /** + * Handle an end-user's decision on an authorization request. This method is + * an alias of the {@link #handle(Params)} method. + * + * @param ticket + * A ticket that was issued by Authlete's {@code /api/auth/authorization} API. + * + * @param claimNames + * Names of requested claims. Use the value of the {@code claims} + * parameter in a response from Authlete's {@code /api/auth/authorization} API. + * + * @param claimLocales + * Requested claim locales. Use the value of the {@code claimsLocales} + * parameter in a response from Authlete's {@code /api/auth/authorization} API. + * + * @param authzIssueOptions + * The request options for the {@code /api/auth/authorization/issue} API. + * + * @param authzFailOptions + * The request options for the {@code /api/auth/authorization/fail} API. + * + * @return + * A response to the client application. Basically, the response + * will trigger redirection to the client's redirection endpoint. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handle( + String ticket, String[] claimNames, String[] claimLocales, Options authzIssueOptions, + Options authzFailOptions) throws WebApplicationException { Params params = new Params() .setTicket(ticket) .setClaimNames(claimNames) .setClaimLocales(claimLocales) + .setAuthzIssueOptions(authzFailOptions) + .setAuthzFailOptions(authzFailOptions) ; return handle(params); @@ -554,7 +699,7 @@ private Response process(Params params) if (mSpi.isClientAuthorized() == false) { // The end-user denied the authorization request. - return fail(params.getTicket(), Reason.DENIED); + return fail(params.getTicket(), Reason.DENIED, params.getAuthzFailOptions()); } // The subject (= unique identifier) of the end-user. @@ -564,7 +709,7 @@ private Response process(Params params) if (subject == null || subject.length() == 0) { // The end-user is not authenticated. - return fail(params.getTicket(), Reason.NOT_AUTHENTICATED); + return fail(params.getTicket(), Reason.NOT_AUTHENTICATED, params.getAuthzFailOptions()); } // the potentially pairwise subject of the end user @@ -619,7 +764,7 @@ private Response process(Params params) // Authorize the authorization request. return authorize(params.getTicket(), subject, authTime, acr, claims, - properties, scopes, sub, claimsForTx, verifiedClaimsForTx); + properties, scopes, sub, claimsForTx, verifiedClaimsForTx, params.getAuthzIssueOptions()); } @@ -1010,6 +1155,9 @@ private VerifiedClaimsCollector createVerifiedClaimsCollector() * Authlete computes values of transformed claims under * {@code verified_claims/claims}. * + * @param options + * The request options for the {@code /auth/authorization/issue} API. + * * @return * A response that should be returned to the client application. */ @@ -1017,7 +1165,7 @@ private Response authorize( String ticket, String subject, long authTime, String acr, Map claims, Property[] properties, String[] scopes, String sub, Map claimsForTx, - List> verifiedClaimsForTx) + List> verifiedClaimsForTx, Options options) { try { @@ -1027,7 +1175,7 @@ private Response authorize( // the generated response, though. return getApiCaller().authorizationIssue( ticket, subject, authTime, acr, claims, properties, - scopes, sub, claimsForTx, verifiedClaimsForTx); + scopes, sub, claimsForTx, verifiedClaimsForTx, options); } catch (WebApplicationException e) { @@ -1049,16 +1197,19 @@ private Response authorize( * @param reason * A reason of the failure of the authorization request. * + * @param options + * The request options for the {@code /auth/authorization/fail} API. + * * @return * A response that should be returned to the client application. */ - private Response fail(String ticket, Reason reason) + private Response fail(String ticket, Reason reason, Options options) { try { // Generate an error response to indicate that // the authorization request failed. - return getApiCaller().authorizationFail(ticket, reason).getResponse(); + return getApiCaller().authorizationFail(ticket, reason, options).getResponse(); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/AuthorizationRequestHandler.java b/src/main/java/com/authlete/jakarta/AuthorizationRequestHandler.java index 47cc7a4..e2502b1 100644 --- a/src/main/java/com/authlete/jakarta/AuthorizationRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/AuthorizationRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2019 Authlete, Inc. + * Copyright (C) 2015-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.AuthorizationFailRequest.Reason; import com.authlete.common.dto.AuthorizationResponse; import com.authlete.common.dto.Property; @@ -74,9 +75,41 @@ public AuthorizationRequestHandler(AuthleteApi api, AuthorizationRequestHandlerS * Handle an authorization request to a authorization endpoint * of OAuth 2.0 (RFC 6749). + * This method is an alias of {@link #handle(MultivaluedMap, Options, Options, Options) + * handle}{@code (parameters, null, null, null)}. * * @param parameters - * Request parameters of an authorization request. + * The request parameters of an authorization request. + * + * @return + * A response that should be returned from the endpoint to the client + * application. + * + * @throws WebApplicationException + * An error occurred. + */ + public Response handle(MultivaluedMap parameters) throws WebApplicationException + { + return handle(parameters, null, null, null); + } + + + /** + * Handle an authorization request to a authorization endpoint + * of OAuth 2.0 (RFC 6749). + * + * @param parameters + * The request parameters of an authorization request. + * + * @param authzOptions + * The request options for the {@code /api/auth/authorization} API. + * + * @param authzIssueOptions + * The request options for the {@code /api/auth/authorization/issue} API. + * + * @param authzFailOptions + * The request options for the {@code /api/auth/authorization/fail} API. * * @return * A response that should be returned from the endpoint to the @@ -84,13 +117,17 @@ public AuthorizationRequestHandler(AuthleteApi api, AuthorizationRequestHandlerS * * @throws WebApplicationException * An error occurred. + * + * @since 2.82 */ - public Response handle(MultivaluedMap parameters) throws WebApplicationException + public Response handle( + MultivaluedMap parameters, Options authzOptions, + Options authzIssueOptions, Options authzFailOptions) throws WebApplicationException { try { // Process the given parameters. - return process(parameters); + return process(parameters, authzOptions, authzIssueOptions, authzFailOptions); } catch (WebApplicationException e) { @@ -107,10 +144,12 @@ public Response handle(MultivaluedMap parameters) throws WebAppl /** * Process the authorization request. */ - private Response process(MultivaluedMap parameters) + private Response process( + MultivaluedMap parameters, Options authzOptions, + Options authzIssueOptions, Options authzFailOptions) { // Call Authlete's /api/auth/authorization API. - AuthorizationResponse response = getApiCaller().callAuthorization(parameters); + AuthorizationResponse response = getApiCaller().callAuthorization(parameters, authzOptions); // 'action' in the response denotes the next action which // this service implementation should take. @@ -147,7 +186,7 @@ private Response process(MultivaluedMap parameters) // Process the authorization request without user interaction. // The flow reaches here only when the authorization request // contained prompt=none. - return handleNoInteraction(response); + return handleNoInteraction(response, authzIssueOptions, authzFailOptions); default: // This never happens. @@ -170,16 +209,17 @@ private Response handleInteraction(AuthorizationResponse response) * Handle the case where {@code action} parameter in a response from * Authlete's {@code /api/auth/authorization} API is {@code NO_INTERACTION}. */ - private Response handleNoInteraction(AuthorizationResponse response) + private Response handleNoInteraction( + AuthorizationResponse response, Options authzIssueOptions, Options authzFailOptions) { // Check 1. End-User Authentication - noInteractionCheckAuthentication(response); + noInteractionCheckAuthentication(response, authzFailOptions); // Get the time when the user was authenticated. long authTime = mSpi.getUserAuthenticatedAt(); // Check 2. Max Age - noInteractionCheckMaxAge(response, authTime); + noInteractionCheckMaxAge(response, authTime, authzFailOptions); // The current subject, i.e. the unique ID assigned by // the service to the current user. @@ -189,14 +229,14 @@ private Response handleNoInteraction(AuthorizationResponse response) String sub = mSpi.getSub(); // Check 3. Subject - noInteractionCheckSubject(response, subject); + noInteractionCheckSubject(response, subject, authzFailOptions); // Get the ACR that was satisfied when the current user // was authenticated. String acr = mSpi.getAcr(); // Check 4. ACR - noInteractionCheckAcr(response, acr); + noInteractionCheckAcr(response, acr, authzFailOptions); // Extra properties to associate with an access token and/or // an authorization code. @@ -209,14 +249,14 @@ private Response handleNoInteraction(AuthorizationResponse response) String[] scopes = mSpi.getScopes(); // Issue - return noInteractionIssue(response, authTime, subject, acr, properties, scopes, sub); + return noInteractionIssue(response, authTime, subject, acr, properties, scopes, sub, authzIssueOptions); } /** * Check whether an end-user has already logged in or not. */ - private void noInteractionCheckAuthentication(AuthorizationResponse response) + private void noInteractionCheckAuthentication(AuthorizationResponse response, Options options) { // If the current user has already been authenticated. if (mSpi.isUserAuthenticated()) @@ -226,11 +266,11 @@ private void noInteractionCheckAuthentication(AuthorizationResponse response) } // A user must have logged in. - throw getApiCaller().authorizationFail(response.getTicket(), Reason.NOT_LOGGED_IN); + throw getApiCaller().authorizationFail(response.getTicket(), Reason.NOT_LOGGED_IN, options); } - private void noInteractionCheckMaxAge(AuthorizationResponse response, long authTime) + private void noInteractionCheckMaxAge(AuthorizationResponse response, long authTime, Options options) { // Get the requested maximum authentication age. int maxAge = response.getMaxAge(); @@ -253,11 +293,11 @@ private void noInteractionCheckMaxAge(AuthorizationResponse response, long authT } // The maximum authentication age has elapsed. - throw getApiCaller().authorizationFail(response.getTicket(), Reason.EXCEEDS_MAX_AGE); + throw getApiCaller().authorizationFail(response.getTicket(), Reason.EXCEEDS_MAX_AGE, options); } - private void noInteractionCheckSubject(AuthorizationResponse response, String subject) + private void noInteractionCheckSubject(AuthorizationResponse response, String subject, Options options) { // Get the requested subject. String requestedSubject = response.getSubject(); @@ -277,11 +317,11 @@ private void noInteractionCheckSubject(AuthorizationResponse response, String su } // The current user is different from the requested subject. - throw getApiCaller().authorizationFail(response.getTicket(), Reason.DIFFERENT_SUBJECT); + throw getApiCaller().authorizationFail(response.getTicket(), Reason.DIFFERENT_SUBJECT, options); } - private void noInteractionCheckAcr(AuthorizationResponse response, String acr) + private void noInteractionCheckAcr(AuthorizationResponse response, String acr, Options options) { // Get the list of requested ACRs. String[] requestedAcrs = response.getAcrs(); @@ -307,7 +347,7 @@ private void noInteractionCheckAcr(AuthorizationResponse response, String acr) if (response.isAcrEssential()) { // None of the requested ACRs is satisfied. - throw getApiCaller().authorizationFail(response.getTicket(), Reason.ACR_NOT_SATISFIED); + throw getApiCaller().authorizationFail(response.getTicket(), Reason.ACR_NOT_SATISFIED, options); } // The ACR satisfied when the current user was authenticated @@ -320,7 +360,8 @@ private void noInteractionCheckAcr(AuthorizationResponse response, String acr) private Response noInteractionIssue( AuthorizationResponse response, long authTime, String subject, - String acr, Property[] properties, String[] scopes, String sub) + String acr, Property[] properties, String[] scopes, String sub, + Options options) { // When prompt=none is contained in an authorization request, // response.getClaims() returns null. This means that user @@ -335,6 +376,6 @@ private Response noInteractionIssue( return getApiCaller().authorizationIssue( response.getTicket(), subject, authTime, acr, - (Map) null, properties, scopes, sub); + (Map) null, properties, scopes, sub, options); } } diff --git a/src/main/java/com/authlete/jakarta/BackchannelAuthenticationCompleteRequestHandler.java b/src/main/java/com/authlete/jakarta/BackchannelAuthenticationCompleteRequestHandler.java index dbdda83..9d18151 100644 --- a/src/main/java/com/authlete/jakarta/BackchannelAuthenticationCompleteRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/BackchannelAuthenticationCompleteRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Authlete, Inc. + * Copyright (C) 2019-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.BackchannelAuthenticationCompleteResponse; import com.authlete.common.dto.Property; import com.authlete.common.dto.BackchannelAuthenticationCompleteRequest.Result; @@ -68,7 +69,8 @@ public class BackchannelAuthenticationCompleteRequestHandler extends BaseHandler * @param spi * Implementation of {@link BackchannelAuthenticationCompleteRequestHandlerSpi} interface. */ - public BackchannelAuthenticationCompleteRequestHandler(AuthleteApi api, BackchannelAuthenticationCompleteRequestHandlerSpi spi) + public BackchannelAuthenticationCompleteRequestHandler( + AuthleteApi api, BackchannelAuthenticationCompleteRequestHandlerSpi spi) { super(api); @@ -78,7 +80,8 @@ public BackchannelAuthenticationCompleteRequestHandler(AuthleteApi api, Backchan /** * Handle the result of end-user authentication and authorization in CIBA - * (Client Initiated Backchannel Authentication) flow. + * (Client Initiated Backchannel Authentication) flow. This method is an alias + * of {@link #handle(AuthleteApi, String[], Options) handle}{@code (ticket, claimNames, null)}. * * @param ticket * A ticket that was issued by Authlete's {@code /api/backchannel/authentication} @@ -93,11 +96,38 @@ public BackchannelAuthenticationCompleteRequestHandler(AuthleteApi api, Backchan * An error occurred. */ public void handle(String ticket, String[] claimNames) throws WebApplicationException + { + handle(ticket, claimNames, null); + } + + + /** + * Handle the result of end-user authentication and authorization in CIBA + * (Client Initiated Backchannel Authentication) flow. + * + * @param ticket + * A ticket that was issued by Authlete's {@code /api/backchannel/authentication} + * API. + * + * @param claimNames + * Names of requested claims. Use the value of the {@code claimNames} + * parameter in a response from Authlete's {@code /api/backchannel/authentication} + * API. + * + * @param options + * The request options for the {@code /api/backchannel/authentication/complete} API. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public void handle(String ticket, String[] claimNames, Options options) throws WebApplicationException { try { // Process the given parameters. - process(ticket, claimNames); + process(ticket, claimNames, options); } catch (WebApplicationException e) { @@ -112,11 +142,11 @@ public void handle(String ticket, String[] claimNames) throws WebApplicationExce } - private void process(String ticket, String[] claimNames) + private void process(String ticket, String[] claimNames, Options options) { // Complete the process with the result of end-user authentication and // authorization. - BackchannelAuthenticationCompleteResponse response = complete(ticket, claimNames); + BackchannelAuthenticationCompleteResponse response = complete(ticket, claimNames, options); // 'action' in the response denotes the next action which // this service implementation should take. @@ -148,7 +178,7 @@ private void process(String ticket, String[] claimNames) } - private BackchannelAuthenticationCompleteResponse complete(String ticket, String[] claimNames) + private BackchannelAuthenticationCompleteResponse complete(String ticket, String[] claimNames, Options options) { // Get the authentication result. Result result = mSpi.getResult(); @@ -166,7 +196,7 @@ private BackchannelAuthenticationCompleteResponse complete(String ticket, String // The end-user authorization has not been successfully done. // Then, complete the process with failure. - return fail(ticket, subject, result, errorDescription, errorUri); + return fail(ticket, subject, result, errorDescription, errorUri, options); } // OK. The end-user has successfully authorized the client. @@ -190,13 +220,13 @@ private BackchannelAuthenticationCompleteResponse complete(String ticket, String Property[] properties = mSpi.getProperties(); // Complete the process with successful authorization. - return authorize(ticket, subject, authTime, acr, claims, properties, scopes); + return authorize(ticket, subject, authTime, acr, claims, properties, scopes, options); } /** - * Call Authlete's {@code /api/backchannel/authentication/complete} API with an unsuccessful - * result. + * Call Authlete's {@code /api/backchannel/authentication/complete} API with + * an unsuccessful result. * * @param ticket * A ticket that was issued by Authlete's {@code /api/backchannel/authentication} @@ -214,17 +244,20 @@ private BackchannelAuthenticationCompleteResponse complete(String ticket, String * @param errorUri * The URI of a document which describes the error in detail. * + * @param options + * The request options for the {@code /api/backchannel/authentication/complete} API. + * * @return * A response from Authlete's {@code /api/backchannel/authentication/complete} * API. */ private BackchannelAuthenticationCompleteResponse fail( String ticket, String subject, Result result, String errorDescription, - URI errorUri) + URI errorUri, Options options) { return callBackchannelAuthenticationComplete( ticket, subject, result, 0, null, null, null, null, errorDescription, - errorUri); + errorUri, options); } @@ -259,6 +292,9 @@ private BackchannelAuthenticationCompleteResponse fail( * @param properties * Extra properties to associate with an access token. * + * @param options + * The request options for the {@code /api/backchannel/authentication/complete} API. + * * @param scopes * Scopes to associate with an access token. If {@code null} is given, * the scopes contained in the original backchannel authentication @@ -271,22 +307,22 @@ private BackchannelAuthenticationCompleteResponse fail( */ private BackchannelAuthenticationCompleteResponse authorize( String ticket, String subject, long authTime, String acr, Map claims, - Property[] properties, String[] scopes) + Property[] properties, String[] scopes, Options options) { return callBackchannelAuthenticationComplete( ticket, subject, Result.AUTHORIZED, authTime, acr, claims, properties, - scopes, null, null); + scopes, null, null, options); } private BackchannelAuthenticationCompleteResponse callBackchannelAuthenticationComplete( String ticket, String subject, Result result, long authTime, String acr, Map claims, Property[] properties, String[] scopes, - String errorDescription, URI errorUri) + String errorDescription, URI errorUri, Options options) { return getApiCaller().callBackchannelAuthenticationComplete( ticket, subject, result, authTime, acr, claims, properties, scopes, - errorDescription, errorUri); + errorDescription, errorUri, options); } diff --git a/src/main/java/com/authlete/jakarta/BackchannelAuthenticationRequestHandler.java b/src/main/java/com/authlete/jakarta/BackchannelAuthenticationRequestHandler.java index aebbdbb..dd31d52 100644 --- a/src/main/java/com/authlete/jakarta/BackchannelAuthenticationRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/BackchannelAuthenticationRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Authlete, Inc. + * Copyright (C) 2019-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.BackchannelAuthenticationFailRequest.Reason; import com.authlete.common.dto.BackchannelAuthenticationIssueResponse; import com.authlete.common.dto.BackchannelAuthenticationResponse; @@ -71,7 +72,8 @@ public class BackchannelAuthenticationRequestHandler extends BaseHandler * @param spi * Implementation of {@link BackchannelAuthenticationRequestHandlerSpi} interface. */ - public BackchannelAuthenticationRequestHandler(AuthleteApi api, BackchannelAuthenticationRequestHandlerSpi spi) + public BackchannelAuthenticationRequestHandler( + AuthleteApi api, BackchannelAuthenticationRequestHandlerSpi spi) { super(api); @@ -81,10 +83,12 @@ public BackchannelAuthenticationRequestHandler(AuthleteApi api, BackchannelAuthe /** * Handle a backchannel authentication request to a backchannel authentication - * endpoint of CIBA (Client Initiated Backchannel Authentication). + * endpoint of CIBA (Client Initiated Backchannel Authentication). This method + * is an alias of {@link #handle(MultivaluedMap, String, String[], Options, Options, Options) + * handle}{@code (parameters, authorization, clientCertificatePath, null, null, null)}. * * @param parameters - * Request parameters of a backchannel authentication request. + * The request parameters of a backchannel authentication request. * * @param authorization * The value of {@code Authorization} header in the backchannel authentication @@ -108,6 +112,52 @@ public BackchannelAuthenticationRequestHandler(AuthleteApi api, BackchannelAuthe public Response handle( MultivaluedMap parameters, String authorization, String[] clientCertificatePath) throws WebApplicationException + { + return handle(parameters, authorization, clientCertificatePath, null, null, null); + } + + + /** + * Handle a backchannel authentication request to a backchannel authentication + * endpoint of CIBA (Client Initiated Backchannel Authentication). + * + * @param parameters + * The request parameters of a backchannel authentication request. + * + * @param authorization + * The value of {@code Authorization} header in the backchannel authentication + * request. A client application may embed its pair of client ID and + * client secret in a backchannel authentication request using Basic + * Authentication. + * + * @param clientCertificatePath + * The path of the client's certificate, each in PEM format. The first + * item in the array is the client's certificate itself. May be {@code null} + * if the client did not send a certificate or path. + * + * @param bcAuthOptions + * The request options for the {@code /api/backchannel/authentication} API. + * + * @param bcAuthIssueOptions + * The request options for the {@code /api/backchannel/authentication/issue} API. + * + * @param bcAuthFailOptions + * The request options for the {@code /api/backchannel/authentication/fail} API. + * + * @return + * A response that should be returned from the endpoint to the + * client application. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handle( + MultivaluedMap parameters, String authorization, + String[] clientCertificatePath, Options bcAuthOptions, Options bcAuthIssueOptions, + Options bcAuthFailOptions) throws WebApplicationException { // Convert the value of Authorization header (credentials of // the client application), if any, into BasicCredentials. @@ -121,7 +171,8 @@ public Response handle( try { // Process the given parameters. - return process(parameters, clientId, clientSecret, clientCertificatePath); + return process(parameters, clientId, clientSecret, clientCertificatePath, + bcAuthOptions, bcAuthIssueOptions, bcAuthFailOptions); } catch (WebApplicationException e) { @@ -137,7 +188,8 @@ public Response handle( private Response process( MultivaluedMap parameters, String clientId, - String clientSecret, String[] clientCertificatePath) + String clientSecret, String[] clientCertificatePath, Options bcAuthOptions, + Options bcAuthIssueOptions, Options bcAuthFailOptions) { // TODO: Duplicate code. String clientCertificate = null; @@ -156,7 +208,8 @@ private Response process( // Call Authlete's /api/backchannel/authentication API. BackchannelAuthenticationResponse response = - getApiCaller().callBackchannelAuthentication(parameters, clientId, clientSecret, clientCertificate, clientCertificatePath); + getApiCaller().callBackchannelAuthentication( + parameters, clientId, clientSecret, clientCertificate, clientCertificatePath, bcAuthOptions); // 'action' in the response denotes the next action which // this service implementation should take. @@ -183,7 +236,7 @@ private Response process( case USER_IDENTIFICATION: // Process user identification. - return handleUserIdentification(response); + return handleUserIdentification(response, bcAuthIssueOptions, bcAuthFailOptions); default: // This never happens. @@ -192,26 +245,27 @@ private Response process( } - private Response handleUserIdentification(BackchannelAuthenticationResponse baRes) + private Response handleUserIdentification( + BackchannelAuthenticationResponse baRes, Options bcAuthIssueOptions, Options bcAuthFailOptions) { // Identify a user based on the hint contained in the backchannel authentication // request. - User user = identifyUserByHint(baRes); + User user = identifyUserByHint(baRes, bcAuthFailOptions); // Check the expiration of the login hint token if necessary. - checkExpirationOfLoginHintToken(baRes); + checkExpirationOfLoginHintToken(baRes, bcAuthFailOptions); // Check the user code contained in the backchannel authentication request // if necessary. - checkUserCode(baRes, user); + checkUserCode(baRes, user, bcAuthFailOptions); // Check the binding message in the backchannel authentication request // if necessary. - checkBindingMessage(baRes); + checkBindingMessage(baRes, bcAuthFailOptions); // Issue an 'auth_req_id'. BackchannelAuthenticationIssueResponse baiRes = - getApiCaller().callBackchannelAuthenticationIssue(baRes.getTicket()); + getApiCaller().callBackchannelAuthenticationIssue(baRes.getTicket(), bcAuthIssueOptions); // 'action' in the response denotes the next action which this service // implementation should take. @@ -244,7 +298,7 @@ private Response handleUserIdentification(BackchannelAuthenticationResponse baRe } - private User identifyUserByHint(BackchannelAuthenticationResponse baRes) + private User identifyUserByHint(BackchannelAuthenticationResponse baRes, Options bcAuthFailOptions) { // Get a user by the hint. User user = mSpi.getUserByHint(baRes.getHintType(), baRes.getHint(), baRes.getSub()); @@ -261,11 +315,13 @@ private User identifyUserByHint(BackchannelAuthenticationResponse baRes) } // Can't identify a user by the hint. - throw getApiCaller().backchannelAuthenticationFail(baRes.getTicket(), Reason.UNKNOWN_USER_ID); + throw getApiCaller().backchannelAuthenticationFail( + baRes.getTicket(), Reason.UNKNOWN_USER_ID, bcAuthFailOptions); } - private void checkExpirationOfLoginHintToken(BackchannelAuthenticationResponse baRes) + private void checkExpirationOfLoginHintToken( + BackchannelAuthenticationResponse baRes, Options bcAuthFailOptions) { if (baRes.getHintType() != UserIdentificationHintType.LOGIN_HINT_TOKEN) { @@ -284,11 +340,11 @@ private void checkExpirationOfLoginHintToken(BackchannelAuthenticationResponse b } // The login hint token has expired. - throw getApiCaller().backchannelAuthenticationFail(baRes.getTicket(), Reason.EXPIRED_LOGIN_HINT_TOKEN); + throw getApiCaller().backchannelAuthenticationFail(baRes.getTicket(), Reason.EXPIRED_LOGIN_HINT_TOKEN, bcAuthFailOptions); } - private void checkUserCode(BackchannelAuthenticationResponse baRes, User user) + private void checkUserCode(BackchannelAuthenticationResponse baRes, User user, Options bcAuthFailOptions) { if (mSpi.shouldCheckUserCode(user, baRes) == false) { @@ -306,11 +362,12 @@ private void checkUserCode(BackchannelAuthenticationResponse baRes, User user) } // The user code is invalid. - throw getApiCaller().backchannelAuthenticationFail(baRes.getTicket(), Reason.INVALID_USER_CODE); + throw getApiCaller().backchannelAuthenticationFail( + baRes.getTicket(), Reason.INVALID_USER_CODE, bcAuthFailOptions); } - private void checkBindingMessage(BackchannelAuthenticationResponse baRes) + private void checkBindingMessage(BackchannelAuthenticationResponse baRes, Options bcAuthFailOptions) { // The binding message in the backchannel authentication request. String bindingMessage = baRes.getBindingMessage(); @@ -328,7 +385,8 @@ private void checkBindingMessage(BackchannelAuthenticationResponse baRes) } // The binding message is invalid. - throw getApiCaller().backchannelAuthenticationFail(baRes.getTicket(), Reason.INVALID_BINDING_MESSAGE); + throw getApiCaller().backchannelAuthenticationFail( + baRes.getTicket(), Reason.INVALID_BINDING_MESSAGE, bcAuthFailOptions); } diff --git a/src/main/java/com/authlete/jakarta/BaseAuthorizationDecisionEndpoint.java b/src/main/java/com/authlete/jakarta/BaseAuthorizationDecisionEndpoint.java index d1459b2..5591d40 100644 --- a/src/main/java/com/authlete/jakarta/BaseAuthorizationDecisionEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseAuthorizationDecisionEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2020 Authlete, Inc. + * Copyright (C) 2016-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.jakarta.AuthorizationDecisionHandler.Params; import com.authlete.jakarta.spi.AuthorizationDecisionHandlerSpi; @@ -34,24 +35,42 @@ public class BaseAuthorizationDecisionEndpoint extends BaseEndpoint { /** - * Handle an authorization decision request. + * Handle an authorization decision request. This method is an alias of + * {@link #handle(AuthleteApi, AuthorizationDecisionHandlerSpi, String, String[], + * String[], Options, Options) handle}{@code (api, spi, ticket, claimNames, claimLocales, null, null)}. * - *

    - * This method internally creates a {@link AuthorizationDecisionHandler} instance and - * calls its {@link AuthorizationDecisionHandler#handle(String, String[], String[])} - * method. Then, this method uses the value returned from the {@code handle()} method - * as a response from this method. - *

    + * @param api + * An implementation of {@link AuthleteApi}. * - *

    - * When {@code AuthorizationDecisionHandler.handle()} method raises a {@link - * WebApplicationException}, this method calls {@link #onError(WebApplicationException) - * onError()} method with the exception. The default implementation of {@code onError()} - * does nothing. You - * can override the method as necessary. After calling {@code onError()} method, - * this method calls {@code getResponse()} method of the exception and uses the - * returned value as a response from this method. - *

    + * @param spi + * An implementation of {@link AuthorizationDecisionHandlerSpi}. + * + * @param ticket + * A ticket that was issued by Authlete's {@code /api/auth/authorization} API. + * + * @param claimNames + * Names of requested claims. Use the value of the {@code claims} + * parameter in a response from Authlete's {@code /api/auth/authorization} API. + * + * @param claimLocales + * Requested claim locales. Use the value of the {@code claimsLocales} + * parameter in a response from Authlete's {@code /api/auth/authorization} API. + * + * @return + * A response that should be returned to the client application. + */ + public Response handle( + AuthleteApi api, AuthorizationDecisionHandlerSpi spi, + String ticket, String[] claimNames, String[] claimLocales) + { + return handle(api, spi, ticket, claimNames, claimLocales, null, null); + } + + + /** + * Handle an authorization decision request. This method is an alias of + * {@link #handle(AuthleteApi, AuthorizationDecisionHandlerSpi, Params, Options, + * Options)} method. * * @param api * An implementation of {@link AuthleteApi}. @@ -70,17 +89,28 @@ public class BaseAuthorizationDecisionEndpoint extends BaseEndpoint * Requested claim locales. Use the value of the {@code claimsLocales} * parameter in a response from Authlete's {@code /api/auth/authorization} API. * + * @param authzIssueOptions + * The request options for the {@code /api/auth/authorization/issue} API. + * + * @param authzFailOptions + * The request options for the {@code /api/auth/authorization/fail} API. + * * @return * A response that should be returned to the client application. + * + * @since 2.82 */ public Response handle( AuthleteApi api, AuthorizationDecisionHandlerSpi spi, - String ticket, String[] claimNames, String[] claimLocales) + String ticket, String[] claimNames, String[] claimLocales, Options authzIssueOptions, + Options authzFailOptions) { Params params = new Params() .setTicket(ticket) .setClaimNames(claimNames) .setClaimLocales(claimLocales) + .setAuthzIssueOptions(authzFailOptions) + .setAuthzFailOptions(authzFailOptions) ; return handle(api, spi, params); @@ -92,19 +122,18 @@ public Response handle( * *

    * This method internally creates a {@link AuthorizationDecisionHandler} instance and - * calls its {@link AuthorizationDecisionHandler#handle(String, String[], String[])} - * method. Then, this method uses the value returned from the {@code handle()} method + * calls its {@link AuthorizationDecisionHandler#handle(Params) handle()} method. + * Then, this method uses the value returned from the {@code handle()} method * as a response from this method. *

    * *

    * When {@code AuthorizationDecisionHandler.handle()} method raises a {@link - * WebApplicationException}, this method calls {@link #onError(WebApplicationException) - * onError()} method with the exception. The default implementation of {@code onError()} - * does nothing. You - * can override the method as necessary. After calling {@code onError()} method, - * this method calls {@code getResponse()} method of the exception and uses the - * returned value as a response from this method. + * WebApplicationException}, this method calls {@link #onError(WebApplicationException) onError()} + * method with the exception. The default implementation of {@code onError()} + * does nothing. You can override the method as necessary. After calling {@code + * onError()} method, this method calls {@code getResponse()} method of the + * exception and uses the returned value as a response from this method. *

    * * @param api diff --git a/src/main/java/com/authlete/jakarta/BaseAuthorizationEndpoint.java b/src/main/java/com/authlete/jakarta/BaseAuthorizationEndpoint.java index debf710..00af0c1 100644 --- a/src/main/java/com/authlete/jakarta/BaseAuthorizationEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseAuthorizationEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2020 Authlete, Inc. + * Copyright (C) 2016-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.jakarta.spi.AuthorizationRequestHandlerSpi; @@ -45,24 +46,48 @@ */ public class BaseAuthorizationEndpoint extends BaseEndpoint { + /** + * Handle an authorization request. This method is an alias of + * {@link #handle(AuthleteApi, AuthorizationRequestHandlerSpi, MultivaluedMap, + * Options, Options, Options) handle}{@code (api, spi, parameters, null, null, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param spi + * An implementation of {@link AuthorizationRequestHandlerSpi}. + * + * @param parameters + * The request parameters of the authorization request. + * + * @return + * A response that should be returned to the client application. + */ + public Response handle( + AuthleteApi api, AuthorizationRequestHandlerSpi spi, + MultivaluedMap parameters) + { + return handle(api, spi, parameters, null, null, null); + } + + /** * Handle an authorization request. * *

    * This method internally creates a {@link AuthorizationRequestHandler} instance and - * calls its {@link AuthorizationRequestHandler#handle(MultivaluedMap)} method. - * Then, this method uses the value returned from the {@code handle()} method - * as a response from this method. + * calls its {@link AuthorizationRequestHandler#handle(MultivaluedMap, Options, + * Options, Options) handle()} method. Then, this method uses the value returned + * from the {@code handle()} method as a response from this method. *

    * *

    * When {@code AuthorizationRequestHandler.handle()} method raises a {@link - * WebApplicationException}, this method calls {@link #onError(WebApplicationException) - * onError()} method with the exception. The default implementation of {@code onError()} - * does nothing. You - * can override the method as necessary. After calling {@code onError()} method, - * this method calls {@code getResponse()} method of the exception and uses the - * returned value as a response from this method. + * WebApplicationException}, this method calls {@link #onError(WebApplicationException) onError()} + * method with the exception. The default implementation of {@code onError()} + * does nothing. You can override the method as necessary. After calling {@code + * onError()} method, this method calls {@code getResponse()} method of the + * exception and uses the returned value as a response from this method. *

    * * @param api @@ -72,14 +97,26 @@ public class BaseAuthorizationEndpoint extends BaseEndpoint * An implementation of {@link AuthorizationRequestHandlerSpi}. * * @param parameters - * Request parameters of the authorization request. + * The request parameters of the authorization request. + * + * @param authzOptions + * The request options for the {@code /api/auth/authorization} API. + * + * @param authzIssueOptions + * The request options for the {@code /api/auth/authorization/issue} API. + * + * @param authzFailOptions + * The request options for the {@code /api/auth/authorization/fail} API. * * @return * A response that should be returned to the client application. + * + * @since 2.82 */ public Response handle( AuthleteApi api, AuthorizationRequestHandlerSpi spi, - MultivaluedMap parameters) + MultivaluedMap parameters, Options authzOptions, + Options authzIssueOptions, Options authzFailOptions) { try { @@ -87,7 +124,7 @@ public Response handle( AuthorizationRequestHandler handler = new AuthorizationRequestHandler(api, spi); // Delegate the task to the handler. - return handler.handle(parameters); + return handler.handle(parameters, authzOptions, authzIssueOptions, authzFailOptions); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/BaseBackchannelAuthenticationEndpoint.java b/src/main/java/com/authlete/jakarta/BaseBackchannelAuthenticationEndpoint.java index fe3eb8f..94ae6b9 100644 --- a/src/main/java/com/authlete/jakarta/BaseBackchannelAuthenticationEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseBackchannelAuthenticationEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Authlete, Inc. + * Copyright (C) 2019-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.jakarta.spi.BackchannelAuthenticationRequestHandlerSpi; @@ -34,21 +35,56 @@ */ public class BaseBackchannelAuthenticationEndpoint extends BaseEndpoint { + /** + * Handle a backchannel authentication request in CIBA (Client Initiated + * Backchannel Authentication) flow. This method is an alias of {@link + * #handle(AuthleteApi, BackchannelAuthenticationRequestHandlerSpi, MultivaluedMap, String, String[], Options, Options, Options) + * handle}{@code (api, spi, parameters, authorization, clientCertificatePath, null, null, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param spi + * An implementation of {@link BackchannelAuthenticationRequestHandlerSpi}. + * + * @param parameters + * The request parameters of the backchannel authentication request. + * + * @param authorization + * The value of {@code Authorization} header of the backchannel authentication + * request. + * + * @param clientCertificatePath + * The certificate path used in mutual TLS authentication, in PEM format. The + * client's own certificate is the first in this array. Can be {@code null}. + * + * @return + * A response that should be returned to the client application. + */ + public Response handle( + AuthleteApi api, BackchannelAuthenticationRequestHandlerSpi spi, + MultivaluedMap parameters, String authorization, + String[] clientCertificatePath) + { + return handle(api, spi, parameters, authorization, clientCertificatePath, null, null, null); + } + + /** * Handle a backchannel authentication request in CIBA (Client Initiated * Backchannel Authentication) flow. * *

    * This method internally creates a {@link BackchannelAuthenticationRequestHandler} - * instance and calls its {@link BackchannelAuthenticationRequestHandler#handle(MultivaluedMap, String, String[])} - * method. Then, this method uses the value returned from the {@code handle()} - * method as a response from this method. + * instance and calls its {@link BackchannelAuthenticationRequestHandler#handle(MultivaluedMap, String, String[]) + * handle()} method. Then, this method uses the value returned from the {@code + * handle()} method as a response from this method. *

    * *

    * When {@code BackchannelAuthenticationRequestHandler.handle()} method raises a {@link - * WebApplicationException}, this method calls {@link #onError(WebApplicationException) - * onError()} method with the exception. The default implementation of {@code onError()} + * WebApplicationException}, this method calls {@link #onError(WebApplicationException) onError()} + * method with the exception. The default implementation of {@code onError()} * does nothing. You can override the method as necessary. After calling * {@code onError()} method, this method calls {@code getResponse()} method of * the exception and uses the returned value as a response from this method. @@ -61,7 +97,7 @@ public class BaseBackchannelAuthenticationEndpoint extends BaseEndpoint * An implementation of {@link BackchannelAuthenticationRequestHandlerSpi}. * * @param parameters - * Request parameters of the backchannel authentication request. + * The request parameters of the backchannel authentication request. * * @param authorization * The value of {@code Authorization} header of the backchannel authentication @@ -71,20 +107,36 @@ public class BaseBackchannelAuthenticationEndpoint extends BaseEndpoint * The certificate path used in mutual TLS authentication, in PEM format. The * client's own certificate is the first in this array. Can be {@code null}. * + * @param bcAuthOptions + * The request options for the {@code /api/backchannel/authentication} API. + * + * @param bcAuthIssueOptions + * The request options for the {@code /api/backchannel/authentication/issue} API. + * + * @param bcAuthFailOptions + * The request options for the {@code /api/backchannel/authentication/fail} API. + * * @return * A response that should be returned to the client application. + * + * @since 2.82 */ public Response handle( AuthleteApi api, BackchannelAuthenticationRequestHandlerSpi spi, - MultivaluedMap parameters, String authorization, String[] clientCertificatePath) + MultivaluedMap parameters, String authorization, + String[] clientCertificatePath, Options bcAuthOptions, Options bcAuthIssueOptions, + Options bcAuthFailOptions) { try { // Create a handler. - BackchannelAuthenticationRequestHandler handler = new BackchannelAuthenticationRequestHandler(api, spi); + BackchannelAuthenticationRequestHandler handler = + new BackchannelAuthenticationRequestHandler(api, spi); // Delegate the task to the handler. - return handler.handle(parameters, authorization, clientCertificatePath); + return handler.handle( + parameters, authorization, clientCertificatePath, bcAuthOptions, + bcAuthIssueOptions, bcAuthFailOptions); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/BaseClientRegistrationEndpoint.java b/src/main/java/com/authlete/jakarta/BaseClientRegistrationEndpoint.java index 890bd2a..3197b95 100644 --- a/src/main/java/com/authlete/jakarta/BaseClientRegistrationEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseClientRegistrationEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Authlete, Inc. + * Copyright (C) 2019-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; /** @@ -37,21 +38,47 @@ */ public class BaseClientRegistrationEndpoint extends BaseEndpoint { + /** + * Handle a client registration request. This method is an alias of {@link + * #handleGet(AuthleteApi, String, String, Options) handleRegister}{@code + * (api, json, authorization, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param json + * The serialized JSON body of the client registration request. + * + * @param authorization + * The value of {@code Authorization} header of the registration request. + * This is optional. + * + * @return + * A response that should be returned to the client application. + */ + public Response handleRegister( + AuthleteApi api, + String json, + String authorization) + { + return handleRegister(api, json, authorization, null); + } + + /** * Handle a client registration request. * *

    * This method internally creates a {@link ClientRegistrationRequestHandler} - * instance and calls its - * {@link ClientRegistrationRequestHandler#handleRegister(String, String)} + * instance and calls its {@link ClientRegistrationRequestHandler#handleRegister(String, String, Options) handle()} * method. Then, this method uses the value returned from the {@code handle()} * method as a response from this method. *

    * *

    * When {@code ClientRegistrationRequestHandler.handle()} method raises a {@link - * WebApplicationException}, this method calls {@link #onError(WebApplicationException) - * onError()} method with the exception. The default implementation of {@code onError()} + * WebApplicationException}, this method calls {@link #onError(WebApplicationException) onError()} + * method with the exception. The default implementation of {@code onError()} * does nothing. You can override the method as necessary. After calling * {@code onError()} method, this method calls {@code getResponse()} method of * the exception and uses the returned value as a response from this method. @@ -67,19 +94,25 @@ public class BaseClientRegistrationEndpoint extends BaseEndpoint * The value of {@code Authorization} header of the registration request. * This is optional. * + * @param options + * The request options for the {@code /api/client/registration} API. + * * @return * A response that should be returned to the client application. + * + * @since 2.82 */ public Response handleRegister( AuthleteApi api, String json, - String authorization) + String authorization, + Options options) { try { ClientRegistrationRequestHandler handler = new ClientRegistrationRequestHandler(api); - return handler.handleRegister(json, authorization); + return handler.handleRegister(json, authorization, options); } catch (WebApplicationException e) { @@ -90,13 +123,43 @@ public Response handleRegister( } + /** + * Handle a client registration management get request. This method is an alias + * of {@link #handleGet(AuthleteApi, String, String, Options) handle}{@code + * (api, clientId, authorization, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param clientId + * The client ID as determined by the incoming request. You will + * commonly parse this from the incoming request URL as a path + * component. If your Service has its {@code registrationManagementEndpoint} + * property set, Authlete will add the client ID as a path parameter + * to this URI automatically. + * + * @param authorization + * The value of {@code Authorization} header of the registration request. + * This is optional. + * + * @return + * A response that should be returned to the client application. + */ + public Response handleGet( + AuthleteApi api, + String clientId, + String authorization) + { + return handleGet(api, clientId, authorization, null); + } + + /** * Handle a client registration management get request. * *

    * This method internally creates a {@link ClientRegistrationRequestHandler} - * instance and calls its - * {@link ClientRegistrationRequestHandler#handleGet(String, String)} + * instance and calls its {@link ClientRegistrationRequestHandler#handleGet(String, String, Options) handle()} * method. Then, this method uses the value returned from the {@code handle()} * method as a response from this method. *

    @@ -124,19 +187,25 @@ public Response handleRegister( * The value of {@code Authorization} header of the registration request. * This is optional. * + * @param options + * The request options for the {@code /api/client/registration} API. + * * @return * A response that should be returned to the client application. + * + * @since 2.82 */ public Response handleGet( AuthleteApi api, String clientId, - String authorization) + String authorization, + Options options) { try { ClientRegistrationRequestHandler handler = new ClientRegistrationRequestHandler(api); - return handler.handleGet(clientId, authorization); + return handler.handleGet(clientId, authorization, options); } catch (WebApplicationException e) { @@ -147,13 +216,48 @@ public Response handleGet( } + /** + * Handle a client registration management update request. This method is an + * alias of the {@link #handleUpdate(AuthleteApi, String, String, String, Options) + * handleUpdate}{@code (api, clientId, json, authorization, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param clientId + * The client ID as determined by the incoming request. You will + * commonly parse this from the incoming request URL as a path + * component. If your Service has its {@code registrationManagementEndpoint} + * property set, Authlete will add the client ID as a path parameter + * to this URI automatically. + * + * @param json + * The serialized JSON body of the client update request. + * + * @param authorization + * The value of {@code Authorization} header of the registration request. + * This is optional. + * + * @return + * A response that should be returned to the client application. + */ + public Response handleUpdate( + AuthleteApi api, + String clientId, + String json, + String authorization) + { + return handleUpdate(api, clientId, json, authorization, null); + } + + /** * Handle a client registration management update request. * *

    * This method internally creates a {@link ClientRegistrationRequestHandler} * instance and calls its - * {@link ClientRegistrationRequestHandler#handleUpdate(String, String, String)} + * {@link ClientRegistrationRequestHandler#handleUpdate(String, String, String) handle()} * method. Then, this method uses the value returned from the {@code handle()} * method as a response from this method. *

    @@ -184,20 +288,26 @@ public Response handleGet( * The value of {@code Authorization} header of the registration request. * This is optional. * + * @param options + * The request options for the {@code /api/client/registration} API. + * * @return * A response that should be returned to the client application. + * + * @since 2.82 */ public Response handleUpdate( AuthleteApi api, String clientId, String json, - String authorization) + String authorization, + Options options) { try { ClientRegistrationRequestHandler handler = new ClientRegistrationRequestHandler(api); - return handler.handleUpdate(clientId, json, authorization); + return handler.handleUpdate(clientId, json, authorization, options); } catch (WebApplicationException e) { @@ -208,13 +318,44 @@ public Response handleUpdate( } + /** + * Handle a client registration management delete request. This method is an + * alias of {@link #handleDelete(AuthleteApi, String, String, Options) handle}{@code + * (api, clientId, authorization, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param clientId + * The client ID as determined by the incoming request. You will + * commonly parse this from the incoming request URL as a path + * component. If your Service has its {@code registrationManagementEndpoint} + * property set, Authlete will add the client ID as a path parameter + * to this URI automatically. + * + * @param authorization + * The value of {@code Authorization} header of the registration request. + * This is optional. + * + * @return + * A response that should be returned to the client application. + */ + public Response handleDelete( + AuthleteApi api, + String clientId, + String authorization) + { + return handleDelete(api, clientId, authorization, null); + } + + /** * Handle a client registration management delete request. * *

    * This method internally creates a {@link ClientRegistrationRequestHandler} * instance and calls its - * {@link ClientRegistrationRequestHandler#handleDelete(String, String)} + * {@link ClientRegistrationRequestHandler#handleDelete(String, String) handle()} * method. Then, this method uses the value returned from the {@code handle()} * method as a response from this method. *

    @@ -242,13 +383,19 @@ public Response handleUpdate( * The value of {@code Authorization} header of the registration request. * This is optional. * + * @param options + * The request options for the {@code /api/client/registration} API. + * * @return * A response that should be returned to the client application. + * + * @since 2.82 */ public Response handleDelete( AuthleteApi api, String clientId, - String authorization) + String authorization, + Options options) { try { diff --git a/src/main/java/com/authlete/jakarta/BaseConfigurationEndpoint.java b/src/main/java/com/authlete/jakarta/BaseConfigurationEndpoint.java index eab7b27..4c01eca 100644 --- a/src/main/java/com/authlete/jakarta/BaseConfigurationEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseConfigurationEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2022 Authlete, Inc. + * Copyright (C) 2016-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.ServiceConfigurationRequest; @@ -71,33 +72,53 @@ */ public class BaseConfigurationEndpoint extends BaseEndpoint { + /** + * Handle a request for OpenID Provider configuration. This method is an alias + * of {@link #handle(AuthleteApi, Options) handle}{@code (api, (Options)null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @return + * A response that should be returned to the client application. + */ + public Response handle(AuthleteApi api) + { + return handle(api, (Options)null); + } + + /** * Handle a request for OpenID Provider configuration. * *

    * This method internally creates a {@link ConfigurationRequestHandler} - * instance and calls its {@link ConfigurationRequestHandler#handle()} method. - * Then, this method uses the value returned from the {@code handle()} method - * as a response from this method. + * instance and calls its {@link ConfigurationRequestHandler#handle(Options)} + * method. Then, this method uses the value returned from the {@code handle()} + * method as a response from this method. *

    * *

    * When {@code ConfigurationRequestHandler.handle()} method raises a {@link - * WebApplicationException}, this method calls {@link #onError(WebApplicationException) - * onError()} method with the exception. The default implementation of {@code onError()} - * does nothing. You - * can override the method as necessary. After calling {@code onError()} method, - * this method calls {@code getResponse()} method of the exception and uses the - * returned value as a response from this method. + * WebApplicationException}, this method calls {@link #onError(WebApplicationException) onError()} + * method with the exception. The default implementation of {@code onError()} + * does nothing. You can override the method as necessary. After calling {@code + * onError()} method, this method calls {@code getResponse()} method of the + * exception and uses the returned value as a response from this method. *

    * * @param api * An implementation of {@link AuthleteApi}. * + * @param options + * The request options for the {@code /api/service/configuration} API. + * * @return * A response that should be returned to the client application. + * + * @since 2.82 */ - public Response handle(AuthleteApi api) + public Response handle(AuthleteApi api, Options options) { try { @@ -105,7 +126,7 @@ public Response handle(AuthleteApi api) ConfigurationRequestHandler handler = new ConfigurationRequestHandler(api); // Delegate the task to the handler. - return handler.handle(); + return handler.handle(options); } catch (WebApplicationException e) { @@ -118,15 +139,37 @@ public Response handle(AuthleteApi api) } + /** + * Handle a request for OpenID Provider configuration. This method is an alias + * of {@link #handle(AuthleteApi, ServiceConfigurationRequest, Options) handle}{@code + * (api, request, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param request + * The request parameters for Authlete's {@code /service/configuration} + * API. + * + * @return + * A response that should be returned from the discovery endpoint. + * + * @since 2.50 + */ + public Response handle(AuthleteApi api, ServiceConfigurationRequest request) + { + return handle(api, request, null); + } + + /** * Handle a request for OpenID Provider configuration. * *

    * This method internally creates a {@link ConfigurationRequestHandler} * instance and calls its - * {@link ConfigurationRequestHandler#handle(ServiceConfigurationRequest) - * handle}{@code (}{@link ServiceConfigurationRequest}{@code )} method. - * Then, this method uses the value returned from the method as a response + * {@link ConfigurationRequestHandler#handle(ServiceConfigurationRequest, Options) handle()} + * method. Then, this method uses the value returned from the method as a response * from this method. *

    * @@ -143,14 +186,19 @@ public Response handle(AuthleteApi api) * An implementation of {@link AuthleteApi}. * * @param request - * Request parameters for Authlete's {@code /service/configuration} API. + * The request parameters for Authlete's {@code /api/service/configuration} + * API. + * + * @param options + * The request options for the {@code /api/service/configuration} API. * * @return * A response that should be returned from the discovery endpoint. * - * @since 2.50 + * @since 2.82 */ - public Response handle(AuthleteApi api, ServiceConfigurationRequest request) + public Response handle( + AuthleteApi api, ServiceConfigurationRequest request, Options options) { try { @@ -158,7 +206,7 @@ public Response handle(AuthleteApi api, ServiceConfigurationRequest request) ConfigurationRequestHandler handler = new ConfigurationRequestHandler(api); // Delegate the task to the handler. - return handler.handle(request); + return handler.handle(request, options); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/BaseCredentialIssuerMetadataEndpoint.java b/src/main/java/com/authlete/jakarta/BaseCredentialIssuerMetadataEndpoint.java index 81db836..f9498d9 100644 --- a/src/main/java/com/authlete/jakarta/BaseCredentialIssuerMetadataEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseCredentialIssuerMetadataEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Authlete, Inc. + * Copyright (C) 2023-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.CredentialIssuerMetadataRequest; @@ -54,24 +55,82 @@ */ public class BaseCredentialIssuerMetadataEndpoint extends BaseEndpoint { + /** + * Handle a request to the credential issuer metadata endpoint. This method is + * an alias of {@link #handle(AuthleteApi, Options) handle}{@code (api, (Options)null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @return + * A response that should be returned from the credential issuer + * metadata endpoint. + */ + public Response handle(AuthleteApi api) + { + return handle(api, (Options)null); + } + + + /** + * Handle a request to the credential issuer metadata endpoint. This method + * is an alias of the {@link #handle(AuthleteApi, CredentialIssuerMetadataRequest, + * Options)} method. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param options + * The request options for the {@code /api/vci/metadata} API. + * + * @return + * A response that should be returned from the credential issuer + * metadata endpoint. + * + * @since 2.82 + */ + public Response handle(AuthleteApi api, Options options) + { + return handle(api, new CredentialIssuerMetadataRequest(), options); + } + + + /** + * Handle a request to the credential issuer metadata endpoint. This method + * is an alias of {@link #handle(AuthleteApi, CredentialIssuerMetadataRequest, + * Options) handle}{@code (api, request, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param request + * The request parameters for Authlete's {@code /api/vci/metadata} API. + * + * @return + * A response that should be returned from the credential issuer + * metadata endpoint. + */ + public Response handle(AuthleteApi api, CredentialIssuerMetadataRequest request) + { + return handle(api, request, null); + } + + /** * Handle a request to the credential issuer metadata endpoint. * *

    * This method internally creates a {@link CredentialIssuerMetadataRequestHandler} - * instance and calls its {@link - * CredentialIssuerMetadataRequestHandler#handle(CredentialIssuerMetadataRequest) - * handle}({@link CredentialIssuerMetadataRequest}) method. - * Then, this method uses the value returned from the handler's method as a - * response from this method. + * instance and calls its {@link CredentialIssuerMetadataRequestHandler#handle(CredentialIssuerMetadataRequest, + * Options) handle()} method. Then, this method uses the value returned from the handler's + * method as a response from this method. *

    * *

    * When the handler's method raises a {@link WebApplicationException}, this - * method calls {@link #onError(WebApplicationException) - * onError(WebApplicationException)} method with the exception. The default - * implementation of {@code onError()} does nothing. You can override the - * method as necessary. After calling {@code onError()} method, this method + * method calls {@link #onError(WebApplicationException) onError()} method with the exception. + * The default implementation of {@code onError()} does nothing. You can override + * the method as necessary. After calling {@code onError()} method, this method * calls {@code getResponse()} method of the exception and uses the returned * value as a response from this method. *

    @@ -79,11 +138,20 @@ public class BaseCredentialIssuerMetadataEndpoint extends BaseEndpoint * @param api * An implementation of {@link AuthleteApi}. * + * @param request + * The request parameters for Authlete's {@code /api/vci/metadata} API. + * + * @param options + * The request options for the {@code /api/vci/metadata} API. + * * @return * A response that should be returned from the credential issuer * metadata endpoint. + * + * @since 2.82 */ - public Response handle(AuthleteApi api, CredentialIssuerMetadataRequest request) + public Response handle( + AuthleteApi api, CredentialIssuerMetadataRequest request, Options options) { try { @@ -92,7 +160,7 @@ public Response handle(AuthleteApi api, CredentialIssuerMetadataRequest request) new CredentialIssuerMetadataRequestHandler(api); // Delegate the task to the handler. - return handler.handle(request); + return handler.handle(request, options); } catch (WebApplicationException e) { @@ -103,26 +171,4 @@ public Response handle(AuthleteApi api, CredentialIssuerMetadataRequest request) return e.getResponse(); } } - - - /** - * Handle a request to the credential issuer metadata endpoint. - * - *

    - * This method is an alias of {@link - * #handle(AuthleteApi, CredentialIssuerMetadataRequest) - * handle}{@code (api, new CredentialIssuerMetadataRequest())} - *

    - * - * @param api - * An implementation of {@link AuthleteApi}. - * - * @return - * A response that should be returned from the credential issuer - * metadata endpoint. - */ - public Response handle(AuthleteApi api) - { - return handle(api, new CredentialIssuerMetadataRequest()); - } } diff --git a/src/main/java/com/authlete/jakarta/BaseCredentialJwtIssuerMetadataEndpoint.java b/src/main/java/com/authlete/jakarta/BaseCredentialJwtIssuerMetadataEndpoint.java index 622854c..ef3d553 100644 --- a/src/main/java/com/authlete/jakarta/BaseCredentialJwtIssuerMetadataEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseCredentialJwtIssuerMetadataEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Authlete, Inc. + * Copyright (C) 2023-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.CredentialJwtIssuerMetadataRequest; @@ -50,24 +51,80 @@ */ public class BaseCredentialJwtIssuerMetadataEndpoint extends BaseEndpoint { + /** + * Handle a request to the JWT issuer metadata endpoint. This method is an alias + * of the {@link #handle(AuthleteApi, CredentialJwtIssuerMetadataRequest)} method. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @return + * A response that should be returned from the JWT issuer + * metadata endpoint. + */ + public Response handle(AuthleteApi api) + { + return handle(api, new CredentialJwtIssuerMetadataRequest()); + } + + + /** + * Handle a request to the JWT issuer metadata endpoint. This method is an alias + * of the {@link #handle(AuthleteApi, CredentialJwtIssuerMetadataRequest, Options)} + * method. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param options + * The request options for the {@code /api/vci/jwtissuer} API. + * + * @return + * A response that should be returned from the JWT issuer + * metadata endpoint. + * + * @since 2.82 + */ + public Response handle(AuthleteApi api, Options options) + { + return handle(api, new CredentialJwtIssuerMetadataRequest(), options); + } + + + /** + * Handle a request to the JWT issuer metadata endpoint. This method is an alias + * of {@link #handle(AuthleteApi, CredentialJwtIssuerMetadataRequest, Options)}{@code + * handle(api, request, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @return + * A response that should be returned from the JWT issuer + * metadata endpoint. + */ + public Response handle(AuthleteApi api, CredentialJwtIssuerMetadataRequest request) + { + return handle(api, request, null); + } + + /** * Handle a request to the JWT issuer metadata endpoint. * *

    - * This method internally creates a {@link - * CredentialJwtIssuerMetadataRequestHandler} instance and calls its {@link - * CredentialJwtIssuerMetadataRequestHandler#handle(CredentialJwtIssuerMetadataRequest) - * handle}({@link CredentialJwtIssuerMetadataRequest}) method. - * Then, this method uses the value returned from the handler's method as a - * response from this method. + * This method internally creates a {@link CredentialJwtIssuerMetadataRequestHandler} + * instance and calls its {@link + * CredentialJwtIssuerMetadataRequestHandler#handle(CredentialJwtIssuerMetadataRequest, Options) handle()} + * method. Then, this method uses the value returned from the handler's method + * as a response from this method. *

    * *

    * When the handler's method raises a {@link WebApplicationException}, this - * method calls {@link #onError(WebApplicationException) - * onError(WebApplicationException)} method with the exception. The default - * implementation of {@code onError()} does nothing. You can override the - * method as necessary. After calling {@code onError()} method, this method + * method calls {@link #onError(WebApplicationException) onError()} method with the exception. + * The default implementation of {@code onError()} does nothing. You can override + * the method as necessary. After calling {@code onError()} method, this method * calls {@code getResponse()} method of the exception and uses the returned * value as a response from this method. *

    @@ -75,11 +132,20 @@ public class BaseCredentialJwtIssuerMetadataEndpoint extends BaseEndpoint * @param api * An implementation of {@link AuthleteApi}. * + * @param request + * The request parameters for Authlete's {@code /api/vci/jwtissuer} API. + * + * @param options + * The request options for the {@code /api/vci/jwtissuer} API. + * * @return * A response that should be returned from the JWT issuer * metadata endpoint. + * + * @since 2.82 */ - public Response handle(AuthleteApi api, CredentialJwtIssuerMetadataRequest request) + public Response handle( + AuthleteApi api, CredentialJwtIssuerMetadataRequest request, Options options) { try { @@ -88,7 +154,7 @@ public Response handle(AuthleteApi api, CredentialJwtIssuerMetadataRequest reque new CredentialJwtIssuerMetadataRequestHandler(api); // Delegate the task to the handler. - return handler.handle(request); + return handler.handle(request, options); } catch (WebApplicationException e) { @@ -99,26 +165,4 @@ public Response handle(AuthleteApi api, CredentialJwtIssuerMetadataRequest reque return e.getResponse(); } } - - - /** - * Handle a request to the JWT issuer metadata endpoint. - * - *

    - * This method is an alias of {@link - * #handle(AuthleteApi, CredentialJwtIssuerMetadataRequest) - * handle}{@code (api, new CredentialJwtIssuerMetadataRequest())} - *

    - * - * @param api - * An implementation of {@link AuthleteApi}. - * - * @return - * A response that should be returned from the JWT issuer - * metadata endpoint. - */ - public Response handle(AuthleteApi api) - { - return handle(api, new CredentialJwtIssuerMetadataRequest()); - } } diff --git a/src/main/java/com/authlete/jakarta/BaseCredentialOfferUriEndpoint.java b/src/main/java/com/authlete/jakarta/BaseCredentialOfferUriEndpoint.java index 4b2bf14..36ffeef 100644 --- a/src/main/java/com/authlete/jakarta/BaseCredentialOfferUriEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseCredentialOfferUriEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2023 Authlete, Inc. + * Copyright (C) 2016-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,12 +20,20 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.CredentialOfferInfoRequest; public class BaseCredentialOfferUriEndpoint extends BaseEndpoint { public Response handle(final AuthleteApi api, final CredentialOfferInfoRequest request) + { + return handle(api, request, null); + } + + + public Response handle( + final AuthleteApi api, final CredentialOfferInfoRequest request, Options options) { try { @@ -33,7 +41,7 @@ public Response handle(final AuthleteApi api, final CredentialOfferInfoRequest r CredentialOfferUriRequestHandler handler = new CredentialOfferUriRequestHandler(api); // Delegate the task to the handler. - return handler.handle(request); + return handler.handle(request, options); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/BaseDeviceAuthorizationEndpoint.java b/src/main/java/com/authlete/jakarta/BaseDeviceAuthorizationEndpoint.java index e1ad99b..60bc6fa 100644 --- a/src/main/java/com/authlete/jakarta/BaseDeviceAuthorizationEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseDeviceAuthorizationEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Authlete, Inc. + * Copyright (C) 2019-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; /** @@ -32,12 +33,47 @@ */ public class BaseDeviceAuthorizationEndpoint extends BaseEndpoint { + /** + * Handle a device authorization request. This method is an alias of {@link + * #handle(AuthleteApi, MultivaluedMap, String, String[], Options) handle}{@code + * (api, parameters, authorization, clientCertificatePath, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param spi + * An implementation of {@link DeviceAuthorizationRequestHandlerSpi}. + * + * @param parameters + * The request parameters of the device authorization request. + * + * @param authorization + * The value of {@code Authorization} header of the device authorization + * request. + * + * @param clientCertificatePath + * The certificate path used in mutual TLS authentication, in PEM format. + * The client's own certificate is the first in this array. Can be + * {@code null}. + * + * @return + * A response that should be returned to the client application. + */ + public Response handle( + AuthleteApi api, MultivaluedMap parameters, String authorization, + String[] clientCertificatePath) + { + return handle(api, parameters, authorization, clientCertificatePath, null); + } + + /** * Handle a device authorization request. * *

    * This method internally creates a {@link DeviceAuthorizationRequestHandler} - * instance and calls its {@link DeviceAuthorizationRequestHandler#handle(MultivaluedMap, String, String[])} + * instance and calls its {@link + * DeviceAuthorizationRequestHandler#handle(MultivaluedMap, String, String[], Options) handle()} * method. Then, this method uses the value returned from the {@code handle()} * method as a response from this method. *

    @@ -59,7 +95,7 @@ public class BaseDeviceAuthorizationEndpoint extends BaseEndpoint * An implementation of {@link DeviceAuthorizationRequestHandlerSpi}. * * @param parameters - * Request parameters of the device authorization request. + * The request parameters of the device authorization request. * * @param authorization * The value of {@code Authorization} header of the device authorization @@ -70,12 +106,17 @@ public class BaseDeviceAuthorizationEndpoint extends BaseEndpoint * The client's own certificate is the first in this array. Can be * {@code null}. * + * @param options + * The request options for the device authorization request. + * * @return * A response that should be returned to the client application. + * + * @since 2.82 */ public Response handle( AuthleteApi api, MultivaluedMap parameters, String authorization, - String[] clientCertificatePath) + String[] clientCertificatePath, Options options) { try { @@ -83,7 +124,7 @@ public Response handle( DeviceAuthorizationRequestHandler handler = new DeviceAuthorizationRequestHandler(api); // Delegate the task to the handler. - return handler.handle(parameters, authorization, clientCertificatePath); + return handler.handle(parameters, authorization, clientCertificatePath, options); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/BaseDeviceCompleteEndpoint.java b/src/main/java/com/authlete/jakarta/BaseDeviceCompleteEndpoint.java index a6ea4a6..d2f35b4 100644 --- a/src/main/java/com/authlete/jakarta/BaseDeviceCompleteEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseDeviceCompleteEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 Authlete, Inc. + * Copyright (C) 2019-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.jakarta.spi.DeviceCompleteRequestHandlerSpi; @@ -33,14 +34,43 @@ */ public class BaseDeviceCompleteEndpoint extends BaseEndpoint { + /** + * Handle a device complete request. This method is an alias of {@link + * #handle(AuthleteApi, DeviceCompleteRequestHandlerSpi, String, String[], Options)}{@code + * (api, spi, userCode, claimNames, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param spi + * An implementation of {@link DeviceCompleteRequestHandlerSpi}. + * + * @param userCode + * The user code that the end-user input. + * + * @param claimNames + * Names of requested claims. Use the value of the {@code claimNames} + * parameter in a response from Authlete's {@code /api/device/verification} API. + * + * @return + * A response that should be returned to the end-user. + */ + public Response handle( + AuthleteApi api, DeviceCompleteRequestHandlerSpi spi, String userCode, + String[] claimNames) + { + return handle(api, spi, userCode, claimNames, null); + } + + /** * Handle a device complete request. * *

    * This method internally creates a {@link DeviceCompleteRequestHandler} instance and - * calls its {@link DeviceCompleteRequestHandler#handle(String, String[])} method. - * Then, this method uses the value returned from the {@code handle()} method - * as a response from this method. + * calls its {@link DeviceCompleteRequestHandler#handle(String, String[], Options) handle()} + * method. Then, this method uses the value returned from the {@code handle()} + * method as a response from this method. *

    * *

    @@ -65,12 +95,17 @@ public class BaseDeviceCompleteEndpoint extends BaseEndpoint * Names of requested claims. Use the value of the {@code claimNames} * parameter in a response from Authlete's {@code /api/device/verification} API. * + * @param options + * The request options for the {@code /api/device/authorization/complete} API. + * * @return * A response that should be returned to the end-user. + * + * @since 2.82 */ public Response handle( AuthleteApi api, DeviceCompleteRequestHandlerSpi spi, String userCode, - String[] claimNames) + String[] claimNames, Options options) { try { @@ -78,7 +113,7 @@ public Response handle( DeviceCompleteRequestHandler handler = new DeviceCompleteRequestHandler(api, spi); // Delegate the task to the handler. - return handler.handle(userCode, claimNames); + return handler.handle(userCode, claimNames, options); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/BaseDeviceVerificationEndpoint.java b/src/main/java/com/authlete/jakarta/BaseDeviceVerificationEndpoint.java index 94d2bd8..8a827e9 100644 --- a/src/main/java/com/authlete/jakarta/BaseDeviceVerificationEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseDeviceVerificationEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Authlete, Inc. + * Copyright (C) 2019-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.jakarta.spi.DeviceVerificationRequestHandlerSpi; @@ -32,20 +33,40 @@ */ public class BaseDeviceVerificationEndpoint extends BaseEndpoint { + /** + * Handle a device verification request. This method is an alias of {@link + * #handle(AuthleteApi, DeviceVerificationRequestHandlerSpi, Options) handle}{@code + * (api, spi, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param spi + * An implementation of {@link DeviceVerificationRequestHandlerSpi}. + * + * @return + * A response that should be returned to the end-user. + */ + public Response handle(AuthleteApi api, DeviceVerificationRequestHandlerSpi spi) + { + return handle(api, spi, null); + } + + /** * Handle a device verification request. * *

    * This method internally creates a {@link DeviceVerificationRequestHandler} - * instance and calls its {@link DeviceVerificationRequestHandler#handle()} + * instance and calls its {@link DeviceVerificationRequestHandler#handle(Options) handle()} * method. Then, this method uses the value returned from the {@code handle()} * method as a response from this method. *

    * *

    * When {@code DeviceVerificationRequestHandler.handle()} method raises a {@link - * WebApplicationException}, this method calls {@link #onError(WebApplicationException) - * onError()} method with the exception. The default implementation of {@code onError()} + * WebApplicationException}, this method calls {@link #onError(WebApplicationException) onError()} + * method with the exception. The default implementation of {@code onError()} * does nothing. You can override the method as necessary. After calling * {@code onError()} method, this method calls {@code getResponse()} method of * the exception and uses the returned value as a response from this method. @@ -57,10 +78,16 @@ public class BaseDeviceVerificationEndpoint extends BaseEndpoint * @param spi * An implementation of {@link DeviceVerificationRequestHandlerSpi}. * + * @param options + * The request options for the {@code /api/device/authorization/verification} API. + * * @return * A response that should be returned to the end-user. + * + * @since 2.82 */ - public Response handle(AuthleteApi api, DeviceVerificationRequestHandlerSpi spi) + public Response handle( + AuthleteApi api, DeviceVerificationRequestHandlerSpi spi, Options options) { try { @@ -68,7 +95,7 @@ public Response handle(AuthleteApi api, DeviceVerificationRequestHandlerSpi spi) DeviceVerificationRequestHandler handler = new DeviceVerificationRequestHandler(api, spi); // Delegate the task to the handler. - return handler.handle(); + return handler.handle(options); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/BaseFederationConfigurationEndpoint.java b/src/main/java/com/authlete/jakarta/BaseFederationConfigurationEndpoint.java index 916e2eb..97c6d6e 100644 --- a/src/main/java/com/authlete/jakarta/BaseFederationConfigurationEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseFederationConfigurationEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Authlete, Inc. + * Copyright (C) 2022-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.FederationConfigurationRequest; @@ -57,23 +58,82 @@ */ public class BaseFederationConfigurationEndpoint extends BaseEndpoint { + /** + * Handle a request to the entity configuration endpoint. This method is an alias + * of the {@link #handle(AuthleteApi, FederationConfigurationRequest)} method. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @return + * A response that should be returned from the entity configuration + * endpoint. + */ + public Response handle(AuthleteApi api) + { + return handle(api, new FederationConfigurationRequest()); + } + + + /** + * Handle a request to the entity configuration endpoint. This method is an + * alias of the {@link #handle(AuthleteApi, FederationConfigurationRequest, Options)} + * method. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param options + * The request options for the {@code /api/federation/configuration} API. + * + * @return + * A response that should be returned from the entity configuration + * endpoint. + * + * @since 2.82 + */ + public Response handle(AuthleteApi api, Options options) + { + return handle(api, new FederationConfigurationRequest(), null); + } + + + /** + * Handle a request to the entity configuration endpoint. This method is an + * alias of {@link #handle(AuthleteApi, FederationConfigurationRequest, Options) + * handle}{@code (api, request, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param request + * The request parameters for Authlete's {@code /api/federation/configuration} API. + * + * @return + * A response that should be returned from the entity configuration + * endpoint. + */ + public Response handle(AuthleteApi api, FederationConfigurationRequest request) + { + return handle(api, request, null); + } + + /** * Handle a request to the entity configuration endpoint. * *

    * This method internally creates a {@link FederationConfigurationRequestHandler} * instance and calls its {@link - * FederationConfigurationRequestHandler#handle(FederationConfigurationRequest) - * handle}({@link FederationConfigurationRequest}) method. - * Then, this method uses the value returned from the handler's method as a - * response from this method. + * FederationConfigurationRequestHandler#handle(FederationConfigurationRequest, Options) handle()} + * method. Then, this method uses the value returned from the handler's method + * as a response from this method. *

    * *

    * When the handler's method raises a {@link WebApplicationException}, this - * method calls {@link #onError(WebApplicationException) - * onError(WebApplicationException)} method with the exception. The default - * implementation of {@code onError()} does nothing. You can override the + * method calls {@link #onError(WebApplicationException) onError()} method with the exception. + * The default implementation of {@code onError()} does nothing. You can override the * method as necessary. After calling {@code onError()} method, this method * calls {@code getResponse()} method of the exception and uses the returned * value as a response from this method. @@ -82,11 +142,20 @@ public class BaseFederationConfigurationEndpoint extends BaseEndpoint * @param api * An implementation of {@link AuthleteApi}. * + * @param request + * The request parameters for Authlete's {@code /api/federation/configuration} API. + * + * @param options + * The request options for the {@code /api/federation/configuration} API. + * * @return * A response that should be returned from the entity configuration * endpoint. + * + * @since 2.82 */ - public Response handle(AuthleteApi api, FederationConfigurationRequest request) + public Response handle( + AuthleteApi api, FederationConfigurationRequest request, Options options) { try { @@ -95,7 +164,7 @@ public Response handle(AuthleteApi api, FederationConfigurationRequest request) new FederationConfigurationRequestHandler(api); // Delegate the task to the handler. - return handler.handle(request); + return handler.handle(request, options); } catch (WebApplicationException e) { @@ -106,26 +175,4 @@ public Response handle(AuthleteApi api, FederationConfigurationRequest request) return e.getResponse(); } } - - - /** - * Handle a request to the entity configuration endpoint. - * - *

    - * This method is an alias of {@link - * #handle(AuthleteApi, FederationConfigurationRequest) - * handle}{@code (api, new FederationConfigurationRequest())} - *

    - * - * @param api - * An implementation of {@link AuthleteApi}. - * - * @return - * A response that should be returned from the entity configuration - * endpoint. - */ - public Response handle(AuthleteApi api) - { - return handle(api, new FederationConfigurationRequest()); - } } diff --git a/src/main/java/com/authlete/jakarta/BaseFederationRegistrationEndpoint.java b/src/main/java/com/authlete/jakarta/BaseFederationRegistrationEndpoint.java index f1eb7ce..e405f87 100644 --- a/src/main/java/com/authlete/jakarta/BaseFederationRegistrationEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseFederationRegistrationEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Authlete, Inc. + * Copyright (C) 2022-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.FederationRegistrationRequest; @@ -80,36 +81,64 @@ */ public class BaseFederationRegistrationEndpoint extends BaseEndpoint { + /** + * Handle a request to the federation registration endpoint. This method is an alias + * of {@link #handle(AuthleteApi, FederationRegistrationRequest, Options) handle}{@code + * (api, request, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param request + * The request parameters for Authlete's {@code /api/federation/registration} API. + * + * @return + * A response that should be returned from the federation + * registration endpoint. + */ + public Response handle(AuthleteApi api, FederationRegistrationRequest request) + { + return handle(api, request, null); + } + + /** * Handle a request to the federation registration endpoint. * *

    * This method internally creates a {@link FederationRegistrationRequestHandler} * instance and calls its {@link - * FederationRegistrationRequestHandler#handle(FederationRegistrationRequest) - * handle}({@link FederationRegistrationRequest}) method. - * Then, this method uses the value returned from the handler's method as a - * response from this method. + * FederationRegistrationRequestHandler#handle(FederationRegistrationRequest, Options) handle()} + * method. Then, this method uses the value returned from the handler's method + * as a response from this method. *

    * *

    * When the handler's method raises a {@link WebApplicationException}, this - * method calls {@link #onError(WebApplicationException) - * onError(WebApplicationException)} method with the exception. The default - * implementation of {@code onError()} does nothing. You can override the - * method as necessary. After calling {@code onError()} method, this method - * calls {@code getResponse()} method of the exception and uses the returned - * value as a response from this method. + * method calls {@link #onError(WebApplicationException) onError()} method with + * the exception. The default implementation of {@code onError()} does nothing. + * You can override the method as necessary. After calling {@code onError()} + * method, this method calls {@code getResponse()} method of the exception and + * uses the returned value as a response from this method. *

    * * @param api * An implementation of {@link AuthleteApi}. * + * @param request + * The request parameters for Authlete's {@code /api/federation/registration} API. + * + * @param options + * The request options for the {@code /api/federation/registration} API. + * * @return * A response that should be returned from the federation * registration endpoint. + * + * @since 2.82 */ - public Response handle(AuthleteApi api, FederationRegistrationRequest request) + public Response handle( + AuthleteApi api, FederationRegistrationRequest request, Options options) { try { @@ -118,7 +147,7 @@ public Response handle(AuthleteApi api, FederationRegistrationRequest request) new FederationRegistrationRequestHandler(api); // Delegate the task to the handler. - return handler.handle(request); + return handler.handle(request, options); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/BaseGrantManagementEndpoint.java b/src/main/java/com/authlete/jakarta/BaseGrantManagementEndpoint.java index c9e46ea..edb224a 100644 --- a/src/main/java/com/authlete/jakarta/BaseGrantManagementEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseGrantManagementEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Authlete, Inc. + * Copyright (C) 2021-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.GMRequest; import com.authlete.common.types.GMAction; @@ -36,13 +37,41 @@ */ public class BaseGrantManagementEndpoint extends BaseResourceEndpoint { + /** + * Handle a grant management request. This method is an alias of {@link + * #handle(AuthleteApi, HttpServletRequest, String, Options) handle}{@code + * (api, req, grantId, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param req + * An HTTP request that the grant management endpoint received. + * Its HTTP method must be either {@code GET} or {@code DELETE}. + * + * @param grantId + * The grant ID included in the API call to the grant management + * endpoint. The last part of the path of the URL. + * + * @return + * A response that should be returned to the client application. + * + * @throws WebApplicationException + * An exception generated by {@link GMRequestHandler}. + */ + public Response handle( + AuthleteApi api, HttpServletRequest req, String grantId) throws WebApplicationException + { + return handle(api, req, grantId, null); + } + + /** * Handle a grant management request. * *

    * This method internally creates a {@link GMRequestHandler} instance and - * calls its {@link GMRequestHandler#handle(GMRequest) handle}({@link - * GMRequest}) method. + * calls its {@link GMRequestHandler#handle(GMRequest, Options)} method. *

    * * @param api @@ -56,15 +85,19 @@ public class BaseGrantManagementEndpoint extends BaseResourceEndpoint * The grant ID included in the API call to the grant management * endpoint. The last part of the path of the URL. * + * @param options + * The request options for the {@code /api/gm} API. + * * @return * A response that should be returned to the client application. * * @throws WebApplicationException * An exception generated by {@link GMRequestHandler}. + * + * @since 2.82 */ public Response handle( - AuthleteApi api, HttpServletRequest req, String grantId) - throws WebApplicationException + AuthleteApi api, HttpServletRequest req, String grantId, Options options) throws WebApplicationException { // Construct request parameters for an API call to the /api/gm API. GMRequest request = buildRequest(req, grantId); @@ -73,7 +106,7 @@ public Response handle( GMRequestHandler handler = new GMRequestHandler(api); // Call the /api/gm API and handle the response. - return handler.handle(request); + return handler.handle(request, options); } diff --git a/src/main/java/com/authlete/jakarta/BaseIntrospectionEndpoint.java b/src/main/java/com/authlete/jakarta/BaseIntrospectionEndpoint.java index b3bb9d3..03a0ec8 100644 --- a/src/main/java/com/authlete/jakarta/BaseIntrospectionEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseIntrospectionEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2023 Authlete, Inc. + * Copyright (C) 2017-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.jakarta.IntrospectionRequestHandler.Params; @@ -39,24 +40,48 @@ public class BaseIntrospectionEndpoint extends BaseEndpoint { /** - * Handle an introspection request. - * - * This method is an alias of the {@link #handle(AuthleteApi, - * IntrospectionRequestHandler.Params)} method. + * Handle an introspection request. This method is an alias of {@link + * #handle(AuthleteApi, MultivaluedMap, Options) handle}{@code (api, parameters, null)}. * * @param api * An implementation of {@link AuthleteApi}. * * @param parameters - * Request parameters of an introspection request. + * The request parameters of an introspection request. * * @return * A response that should be returned to the resource server. */ public Response handle(AuthleteApi api, MultivaluedMap parameters) + { + return handle(api, parameters, null); + } + + + /** + * Handle an introspection request. This method is an alias of the {@link + * #handle(AuthleteApi, IntrospectionRequestHandler.Params)} method. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param parameters + * The request parameters of an introspection request. + * + * @param options + * The request options for the {@code /api/auth/introspection} API. + * + * @return + * A response that should be returned to the resource server. + * + * @since 2.82 + */ + public Response handle( + AuthleteApi api, MultivaluedMap parameters, Options options) { Params params = new Params() .setParameters(parameters) + .setOptions(options) ; return handle(api, params); @@ -68,8 +93,9 @@ public Response handle(AuthleteApi api, MultivaluedMap parameter * *

    * This method internally creates an {@link IntrospectionRequestHandler} - * instance and calls its {@link IntrospectionRequestHandler#handle(IntrospectionRequestHandler.Params) - * handle()} method with the {@code params} argument. Then, this + * instance and calls its {@link + * IntrospectionRequestHandler#handle(IntrospectionRequestHandler.Params) handle()} + * method with the {@code params} argument. Then, this * method uses the value returned from the {@code handle()} method * as a response from this method. *

    diff --git a/src/main/java/com/authlete/jakarta/BaseJwksEndpoint.java b/src/main/java/com/authlete/jakarta/BaseJwksEndpoint.java index 7e4fc71..4f386f1 100644 --- a/src/main/java/com/authlete/jakarta/BaseJwksEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseJwksEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2020 Authlete, Inc. + * Copyright (C) 2016-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; /** @@ -51,20 +52,36 @@ */ public class BaseJwksEndpoint extends BaseEndpoint { + /** + * Handle a request for a JWK Set document. This method is an alias of {@link + * #handle(AuthleteApi, Options) handle}{@code (api, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @return + * A response that should be returned to the client application. + */ + public Response handle(AuthleteApi api) + { + return handle(api, null); + } + + /** * Handle a request for a JWK Set document. * *

    * This method internally creates a {@link JwksRequestHandler} instance and - * calls its {@link JwksRequestHandler#handle()} method. Then, this method - * uses the value returned from the {@code handle()} method as a response - * from this method. + * calls its {@link JwksRequestHandler#handle(Options) handle()} method. Then, + * this method uses the value returned from the {@code handle()} method as a + * response from this method. *

    * *

    * When {@code JwksRequestHandler.handle()} method raises a {@link - * WebApplicationException}, this method calls {@link #onError(WebApplicationException) - * onError()} method with the exception. The default implementation of {@code onError()} + * WebApplicationException}, this method calls {@link #onError(WebApplicationException) onError()} + * method with the exception. The default implementation of {@code onError()} * does nothing. You * can override the method as necessary. After calling {@code onError()} method, * this method calls {@code getResponse()} method of the exception and uses the @@ -74,10 +91,15 @@ public class BaseJwksEndpoint extends BaseEndpoint * @param api * An implementation of {@link AuthleteApi}. * + * @param options + * The request options for the {@code /api/service/jwks/get} API. + * * @return * A response that should be returned to the client application. + * + * @since 2.82 */ - public Response handle(AuthleteApi api) + public Response handle(AuthleteApi api, Options options) { try { @@ -85,7 +107,7 @@ public Response handle(AuthleteApi api) JwksRequestHandler handler = new JwksRequestHandler(api); // Delegate the task to the handler. - return handler.handle(); + return handler.handle(options); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/BasePushedAuthReqEndpoint.java b/src/main/java/com/authlete/jakarta/BasePushedAuthReqEndpoint.java index 265ffaa..99b6c63 100644 --- a/src/main/java/com/authlete/jakarta/BasePushedAuthReqEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BasePushedAuthReqEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2023 Authlete, Inc. + * Copyright (C) 2019-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.jakarta.PushedAuthReqHandler.Params; @@ -37,48 +38,68 @@ public class BasePushedAuthReqEndpoint extends BaseEndpoint { /** - * Handle a pushed authorization request. + * Handle a pushed authorization request. This method is an alias of {@link + * #handle(AuthleteApi, MultivaluedMap, String, String[], Options) handle}{@code + * (api, parameters, authorization, clientCertificates, null)}. * - *

    - * This method internally creates a {@link PushedAuthReqHandler} instance - * and calls its {@link PushedAuthReqHandler#handle(MultivaluedMap, String, String[])} - * method. Then, this method uses the value returned from the {@code handle()} - * method as a response from this method. - *

    + * @param api + * An implementation of {@link AuthleteApi}. * - *

    - * When {@code PushedAuthReqHandler.handle()} method raises a {@link - * WebApplicationException}, this method calls {@link #onError(WebApplicationException) - * onError()} method with the exception. The default implementation of {@code onError()} - * does nothing. You can override the method as necessary. After calling - * {@code onError()} method, this method calls {@code getResponse()} method of - * the exception and uses the returned value as a response from this method. - *

    + * @param parameters + * The request parameters of the pushed authorization request. + * + * @param authorization + * The value of {@code Authorization} header of the pushed authorization request. + * + * @param clientCertificates + * The certificate path used in mutual TLS authentication, in PEM format. The + * client's own certificate is the first in this array. Can be {@code null}. + * + * @return + * A response that should be returned to the client application. + */ + protected Response handle( + AuthleteApi api, MultivaluedMap parameters, + String authorization, String[] clientCertificates) + { + return handle(api, parameters, authorization, clientCertificates, null); + } + + + /** + * Handle a pushed authorization request. This method is an alias of {@link + * #handle(AuthleteApi, Params) handle}{@code (api, params)}. * * @param api - * An implementation of {@link AuthleteApi}. + * An implementation of {@link AuthleteApi}. * * @param parameters - * Request parameters of the pushed authorization request. + * The request parameters of the pushed authorization request. * * @param authorization - * The value of {@code Authorization} header of the pushed authorization request. + * The value of {@code Authorization} header of the pushed authorization request. * * @param clientCertificates - * The certificate path used in mutual TLS authentication, in PEM format. The - * client's own certificate is the first in this array. Can be {@code null}. + * The certificate path used in mutual TLS authentication, in PEM format. The + * client's own certificate is the first in this array. Can be {@code null}. + * + * @param options + * The request options for the {@code /api/pushed_auth_req} API. * * @return * A response that should be returned to the client application. + * + * @since 2.82 */ protected Response handle( AuthleteApi api, MultivaluedMap parameters, - String authorization, String[] clientCertificates) + String authorization, String[] clientCertificates, Options options) { Params params = new Params() .setParameters(parameters) .setAuthorization(authorization) .setClientCertificatePath(clientCertificates) + .setOptions(options) ; return handle(api, params); @@ -90,15 +111,15 @@ protected Response handle( * *

    * This method internally creates a {@link PushedAuthReqHandler} instance and - * calls its {@link PushedAuthReqHandler#handle(PushedAuthReqHandler.Params) - * handle(Params)} method. Then, this method uses the value returned from - * the {@code handle()} method as a response from this method. + * calls its {@link PushedAuthReqHandler#handle(PushedAuthReqHandler.Params) handle()} + * method. Then, this method uses the value returned from the {@code handle()} + * method as a response from this method. *

    * *

    * When {@code PushedAuthReqHandler.handle()} method raises a {@link - * WebApplicationException}, this method calls {@link #onError(WebApplicationException) - * onError()} method with the exception. The default implementation of {@code onError()} + * WebApplicationException}, this method calls {@link #onError(WebApplicationException) onError()} + * method with the exception. The default implementation of {@code onError()} * does nothing. You can override the method as necessary. After calling * {@code onError()} method, this method calls {@code getResponse()} method of * the exception and uses the returned value as a response from this method. diff --git a/src/main/java/com/authlete/jakarta/BaseResourceEndpoint.java b/src/main/java/com/authlete/jakarta/BaseResourceEndpoint.java index 6c6ad5c..1b2916b 100644 --- a/src/main/java/com/authlete/jakarta/BaseResourceEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseResourceEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2023 Authlete, Inc. + * Copyright (C) 2016-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import jakarta.ws.rs.WebApplicationException; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.IntrospectionRequest; import com.authlete.common.dto.IntrospectionResponse; import com.authlete.common.web.BearerToken; @@ -87,7 +88,8 @@ public String extractAccessToken(String authorization, String accessTokenInReque /** * Validate an access token. This method is an alias of {@link - * #validateAccessToken(AuthleteApi, AccessTokenValidator.Params)}. + * #validateAccessToken(AuthleteApi, String, Options) validateAccessToken}{@code + * (api, accessToken, (Options)null)}. * * @param api * Implementation of {@link AuthleteApi} interface. @@ -105,17 +107,44 @@ public String extractAccessToken(String authorization, String accessTokenInReque public AccessTokenInfo validateAccessToken( AuthleteApi api, String accessToken) throws WebApplicationException { - Params params = new Params() - .setAccessToken(accessToken) - ; + return validateAccessToken(api, accessToken, (Options)null); + } - return validateAccessToken(api, params); + + /** + * Validate an access token. This method is an alias of {@link + * #validateAccessToken(AuthleteApi, String, String[], Options) validateAccessToken}{@code + * (api, accessToken, null, options)}. + * + * @param api + * Implementation of {@link AuthleteApi} interface. + * + * @param accessToken + * An access token to validate. + * + * @param options + * The request options for the {@code /api/auth/introspection} API. + * + * @return + * Information about the access token. + * + * @throws WebApplicationException + * The access token is invalid. To be concrete, the access + * token does not exist or it has expired. + * + * @since 2.82 + */ + public AccessTokenInfo validateAccessToken( + AuthleteApi api, String accessToken, Options options) throws WebApplicationException + { + return validateAccessToken(api, accessToken, null, options); } /** * Validate an access token. This method is an alias of {@link - * #validateAccessToken(AuthleteApi, AccessTokenValidator.Params)}. + * #validateAccessToken(AuthleteApi, String, String[], Options) validateAccessToken}{@code + * (api, accessToken, requiredScopes, (Options)null)}. * * @param api * Implementation of {@link AuthleteApi} interface. @@ -142,18 +171,54 @@ public AccessTokenInfo validateAccessToken( public AccessTokenInfo validateAccessToken( AuthleteApi api, String accessToken, String[] requiredScopes) throws WebApplicationException { - Params params = new Params() - .setAccessToken(accessToken) - .setRequiredScopes(requiredScopes) - ; + return validateAccessToken(api, accessToken, requiredScopes, (Options)null); + } - return validateAccessToken(api, params); + + /** + * Validate an access token. This method is an alias of {@link + * #validateAccessToken(AuthleteApi, String, String[], String, Options) + * validateAccessToken}{@code (api, accessToken, requiredScopes, null, options)}. + * + * @param api + * Implementation of {@link AuthleteApi} interface. + * + * @param accessToken + * An access token to validate. + * + * @param requiredScopes + * Scopes that must be associated with the access token. + * {@code null} is okay. + * + * @param options + * The request options for the {@code /api/auth/introspection} API. + * + * @return + * Information about the access token. + * + * @throws WebApplicationException + * The access token is invalid. To be concrete, one or more of + * the following conditions meet. + *

      + *
    1. The access token does not exist. + *
    2. The access token has expired. + *
    3. The access token does not cover the required scopes. + *
    + * + * @since 2.82 + */ + public AccessTokenInfo validateAccessToken( + AuthleteApi api, String accessToken, String[] requiredScopes, Options options) + throws WebApplicationException + { + return validateAccessToken(api, accessToken, requiredScopes, null, options); } /** * Validate an access token. This method is an alias of {@link - * #validateAccessToken(AuthleteApi, AccessTokenValidator.Params)}. + * #validateAccessToken(AuthleteApi, String, String[], String, Options)}{@code + * (api, accessToken, requiredScopes, requiredSubject, (Options)null)}. * * @param api * Implementation of {@link AuthleteApi} interface. @@ -185,19 +250,60 @@ public AccessTokenInfo validateAccessToken( AuthleteApi api, String accessToken, String[] requiredScopes, String requiredSubject) throws WebApplicationException { - Params params = new Params() - .setAccessToken(accessToken) - .setRequiredScopes(requiredScopes) - .setRequiredSubject(requiredSubject) - ; + return validateAccessToken( + api, accessToken, requiredScopes, requiredSubject, (Options)null); + } - return validateAccessToken(api, params); + + /** + * Validate an access token. This method is an alias of {@link + * #validateAccessToken(AuthleteApi, String, String[], String, String, Options) + * validateAccessToken}{@code (api, accessToken, requiredScopes, requiredSubject, null, null)}. + * + * @param api + * Implementation of {@link AuthleteApi} interface. + * + * @param accessToken + * An access token to validate. + * + * @param requiredScopes + * Scopes that must be associated with the access token. + * {@code null} is okay. + * + * @param requiredSubject + * Subject (= user's unique identifier) that must be associated + * with the access token. {@code null} is okay. + * + * @param options + * The request options for the {@code /api/auth/introspection} API. + * + * @return + * Information about the access token. + * + * @throws WebApplicationException + * The access token is invalid. To be concrete, one or more of + * the following conditions meet. + *
      + *
    1. The access token does not exist. + *
    2. The access token has expired. + *
    3. The access token does not cover the required scopes. + *
    + * + * @since 2.82 + */ + public AccessTokenInfo validateAccessToken( + AuthleteApi api, String accessToken, + String[] requiredScopes, String requiredSubject, Options options) throws WebApplicationException + { + return validateAccessToken( + api, accessToken, requiredScopes, requiredSubject, null, null); } /** * Validate an access token. This method is an alias of {@link - * #validateAccessToken(AuthleteApi, AccessTokenValidator.Params)}. + * #validateAccessToken(AuthleteApi, String, String[], String, String, Options) + * validateAccessToken}{@code (api, accessToken, requiredScopes, requiredSubject, clientCertificate, null)}. * * @param api * Implementation of {@link AuthleteApi} interface. @@ -238,12 +344,65 @@ public AccessTokenInfo validateAccessToken( public AccessTokenInfo validateAccessToken( AuthleteApi api, String accessToken, String[] requiredScopes, String requiredSubject, String clientCertificate) throws WebApplicationException + { + return validateAccessToken( + api, accessToken, requiredScopes, requiredSubject, clientCertificate, null); + } + + + /** + * Validate an access token. This method is an alias of the {@link + * #validateAccessToken(AuthleteApi, AccessTokenValidator.Params)} method. + * + * @param api + * Implementation of {@link AuthleteApi} interface. + * + * @param accessToken + * An access token to validate. + * + * @param requiredScopes + * Scopes that must be associated with the access token. + * {@code null} is okay. + * + * @param requiredSubject + * Subject (= user's unique identifier) that must be associated + * with the access token. {@code null} is okay. + * + * @param clientCertificate + * TLS Certificate of the client presented during a call to + * the resource server, used with TLS-bound access tokens. + * Can be {@code null} if no certificate is presented. + * + * @param options + * The request options for the {@code /api/auth/introspection} API. + * + * @return + * Information about the access token. + * + * @throws WebApplicationException + * The access token is invalid. To be concrete, one or more of + * the following conditions meet. + *
      + *
    1. The access token does not exist. + *
    2. The access token has expired. + *
    3. The access token does not cover the required scopes. + *
    4. The access token is not associated with the required subject. + *
    5. The access token is bound to a client certificate, but the + * given one does not match. + *
    + * + * @since 2.82 + */ + public AccessTokenInfo validateAccessToken( + AuthleteApi api, String accessToken, String[] requiredScopes, + String requiredSubject, String clientCertificate, Options options) throws WebApplicationException { Params params = new Params() .setAccessToken(accessToken) .setRequiredScopes(requiredScopes) .setRequiredSubject(requiredSubject) .setClientCertificate(clientCertificate) + .setOptions(options) ; return validateAccessToken(api, params); @@ -253,25 +412,6 @@ public AccessTokenInfo validateAccessToken( /** * Validate an access token. * - *

    - * This method internally creates an {@link AccessTokenValidator} instance - * and calls its {@link AccessTokenValidator#validate(Params) - * validate()} method. Then, this method uses the value returned from the - * {@code validate()} method as a response from this method. - *

    - * - *

    - * When {@code AccessTokenValidator.validate()} method raises a {@link - * WebApplicationException}, this method calls {@link - * #onError(WebApplicationException) onError()} method with the exception. - * The default implementation of {@code onError()} does nothing. You can - * override the method as necessary. After calling {@code onError()} - * method, this method re-throws the exception. The response contained in - * the exception complies with the requirements described in RFC 6750 (The OAuth 2.0 - * Authorization Framework: Bearer Token Usage). - *

    - * * @param api * Implementation of {@link AuthleteApi} interface. * @@ -306,11 +446,18 @@ public AccessTokenInfo validateAccessToken( public IntrospectionResponse validateAccessToken( AuthleteApi api, IntrospectionRequest request) throws WebApplicationException + { + return validateAccessToken(api, request, null); + } + + + public IntrospectionResponse validateAccessToken( + AuthleteApi api, IntrospectionRequest request, Options options) throws WebApplicationException { try { // Validate the access token and obtain the information about it. - return new AccessTokenValidator(api).validate(request); + return new AccessTokenValidator(api).validate(request, options); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/BaseRevocationEndpoint.java b/src/main/java/com/authlete/jakarta/BaseRevocationEndpoint.java index 99387da..3e1d04a 100644 --- a/src/main/java/com/authlete/jakarta/BaseRevocationEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseRevocationEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2020 Authlete, Inc. + * Copyright (C) 2016-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; /** @@ -37,12 +38,36 @@ */ public class BaseRevocationEndpoint extends BaseEndpoint { + /** + * Handle a revocation request. This method is an alias of {@link + * #handle(AuthleteApi, MultivaluedMap, String, Options) handle}{@code + * (api, parameters, authorization, null)}. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param parameters + * The request parameters of a revocation request. + * + * @param authorization + * The value of {@code Authorization} header. + * + * @return + * A response that should be returned to the client application. + */ + public Response handle( + AuthleteApi api, MultivaluedMap parameters, String authorization) + { + return handle(api, parameters, authorization, null); + } + + /** * Handle a revocation request. * *

    * This method internally creates a {@link RevocationRequestHandler} instance - * and calls its {@link RevocationRequestHandler#handle(MultivaluedMap, String) + * and calls its {@link RevocationRequestHandler#handle(MultivaluedMap, String, Options) * handle()} method with the {@code parameters} argument and the {@code authorization} * argument. Then, this method uses the value returned from the {@code handle()} * method as a response from this method. @@ -50,8 +75,8 @@ public class BaseRevocationEndpoint extends BaseEndpoint * *

    * When {@code RevocationRequestHandler.handle()} method raises a {@link - * WebApplicationException}, this method calls {@link #onError(WebApplicationException) - * onError()} method with the exception. The default implementation of {@code onError()} + * WebApplicationException}, this method calls {@link #onError(WebApplicationException) onError()} + * method with the exception. The default implementation of {@code onError()} * does nothing. You * can override the method as necessary. After calling {@code onError()} method, * this method calls {@code getResponse()} method of the exception and uses the @@ -62,15 +87,22 @@ public class BaseRevocationEndpoint extends BaseEndpoint * An implementation of {@link AuthleteApi}. * * @param parameters - * Request parameters of a revocation request. + * The request parameters of a revocation request. * * @param authorization * The value of {@code Authorization} header. * + * @param options + * The request options for the {@code /api/auth/revocation} API. + * * @return * A response that should be returned to the client application. + * + * @since 2.82 */ - public Response handle(AuthleteApi api, MultivaluedMap parameters, String authorization) + public Response handle( + AuthleteApi api, MultivaluedMap parameters, String authorization, + Options options) { try { @@ -78,7 +110,7 @@ public Response handle(AuthleteApi api, MultivaluedMap parameter RevocationRequestHandler handler = new RevocationRequestHandler(api); // Delegate the task to the handler. - return handler.handle(parameters, authorization); + return handler.handle(parameters, authorization, options); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/BaseTokenEndpoint.java b/src/main/java/com/authlete/jakarta/BaseTokenEndpoint.java index 980813d..4c3c244 100644 --- a/src/main/java/com/authlete/jakarta/BaseTokenEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseTokenEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2022 Authlete, Inc. + * Copyright (C) 2016-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.jakarta.TokenRequestHandler.Params; import com.authlete.jakarta.spi.TokenRequestHandlerSpi; @@ -41,10 +42,9 @@ public class BaseTokenEndpoint extends BaseEndpoint { /** - * Handle a token request. - * - * This method is an alias of the {@link #handle(AuthleteApi, - * TokenRequestHandlerSpi, TokenRequestHandler.Params)} method. + * Handle a token request. This method is an alias of {@link #handle(AuthleteApi, + * TokenRequestHandlerSpi, MultivaluedMap, String, Options, Options, Options) + * handle}{@code (api, spi, parameters, authorization, null, null, null)}. * * @param api * An implementation of {@link AuthleteApi}. @@ -53,7 +53,7 @@ public class BaseTokenEndpoint extends BaseEndpoint * An implementation of {@link TokenRequestHandlerSpi}. * * @param parameters - * Request parameters of the token request. + * The request parameters of the token request. * * @param authorization * The value of {@code Authorization} header of the token request. @@ -65,20 +65,55 @@ public Response handle( AuthleteApi api, TokenRequestHandlerSpi spi, MultivaluedMap parameters, String authorization) { - Params params = new Params() - .setParameters(parameters) - .setAuthorization(authorization) - ; - - return handle(api, spi, params); + return handle(api, spi, parameters, authorization, null, null, null); } /** - * Handle a token request. + * Handle a token request. This method is an alias of the {@link #handle(AuthleteApi, + * TokenRequestHandlerSpi, MultivaluedMap, String, String[], Options) handle}{@code + * (api, spi, parameters, authorization, null, tokenOptions, tokenIssueOptions, tokenFailOptions)}. * - * This method is an alias of the {@link #handle(AuthleteApi, - * TokenRequestHandlerSpi, TokenRequestHandler.Params)} method. + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param spi + * An implementation of {@link TokenRequestHandlerSpi}. + * + * @param parameters + * The request parameters of the token request. + * + * @param authorization + * The value of {@code Authorization} header of the token request. + * + * @param tokenOptions + * The request options for the {@code /api/auth/token} API. + * + * @param tokenIssueOptions + * The request options for the {@code /api/auth/token/issue} API. + * + * @param tokenFailOptions + * The request options for the {@code /api/auth/token/fail} API. + * + * @return + * A response that should be returned to the client application. + * + * @since 2.82 + */ + public Response handle( + AuthleteApi api, TokenRequestHandlerSpi spi, + MultivaluedMap parameters, String authorization, + Options tokenOptions, Options tokenIssueOptions, Options tokenFailOptions) + { + return handle( + api, spi, parameters, authorization, null, tokenOptions, tokenIssueOptions, tokenFailOptions); + } + + + /** + * Handle a token request. This method is an alias of the {@link #handle(AuthleteApi, + * TokenRequestHandlerSpi, MultivaluedMap, String, String[], Options, Options, Options) + * handle}{@code (api, spi, parameters, authorization, clientCertificatePath, null, null, null)}. * * @param api * An implementation of {@link AuthleteApi}. @@ -87,7 +122,7 @@ public Response handle( * An implementation of {@link TokenRequestHandlerSpi}. * * @param parameters - * Request parameters of the token request. + * The request parameters of the token request. * * @param authorization * The value of {@code Authorization} header of the token request. @@ -105,11 +140,60 @@ public Response handle( public Response handle( AuthleteApi api, TokenRequestHandlerSpi spi, MultivaluedMap parameters, String authorization, String[] clientCertificatePath) + { + return handle( + api, spi, parameters, authorization, clientCertificatePath, null, null, null); + } + + + /** + * Handle a token request. This method is an alias of the {@link #handle(AuthleteApi, + * TokenRequestHandlerSpi, TokenRequestHandler.Params)} method. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param spi + * An implementation of {@link TokenRequestHandlerSpi}. + * + * @param parameters + * The request parameters of the token request. + * + * @param authorization + * The value of {@code Authorization} header of the token request. + * + * @param clientCertificatePath + * The certificate path used in mutual TLS authentication, each in + * PEM format. The client's own certificate is the first in this + * array. Can be {@code null}. + * + * @param tokenOptions + * The request options for the {@code /api/auth/token} API. + * + * @param tokenIssueOptions + * The request options for the {@code /api/auth/token/issue} API. + * + * @param tokenFailOptions + * The request options for the {@code /api/auth/token/fail} API. + * + * @return + * A response that should be returned to the client application. + * + * @since 2.82 + */ + public Response handle( + AuthleteApi api, TokenRequestHandlerSpi spi, + MultivaluedMap parameters, String authorization, + String[] clientCertificatePath, Options tokenOptions, Options tokenIssueOptions, + Options tokenFailOptions) { Params params = new Params() .setParameters(parameters) .setAuthorization(authorization) .setClientCertificatePath(clientCertificatePath) + .setTokenOptions(tokenOptions) + .setTokenIssueOptions(tokenIssueOptions) + .setTokenFailOptions(tokenFailOptions) ; return handle(api, spi, params); @@ -121,18 +205,19 @@ public Response handle( * *

    * This method internally creates a {@link TokenRequestHandler} instance and - * calls its {@link TokenRequestHandler#handle(TokenRequestHandler.Params) - * handle(Params)} method. Then, this method uses the value returned from - * the {@code handle()} method as a response from this method. + * calls its {@link TokenRequestHandler#handle(TokenRequestHandler.Params) handle()} + * method. Then, this method uses the value returned from the {@code handle()} + * method as a response from this method. *

    * *

    * When {@code TokenRequestHandler.handle()} method raises a {@link * WebApplicationException}, this method calls {@link #onError(WebApplicationException) - * onError()} method with the exception. The default implementation of {@code onError()} - * does nothing. You can override the method as necessary. After calling - * {@code onError()} method, this method calls {@code getResponse()} method of - * the exception and uses the returned value as a response from this method. + * onError()} method with the exception. The default implementation of {@code + * onError()} does nothing. You can override the method as necessary. After + * calling {@code onError()} method, this method calls {@code getResponse()} + * method of the exception and uses the returned value as a response from this + * method. *

    * * @param api diff --git a/src/main/java/com/authlete/jakarta/BaseUserInfoEndpoint.java b/src/main/java/com/authlete/jakarta/BaseUserInfoEndpoint.java index c60e031..a369da1 100644 --- a/src/main/java/com/authlete/jakarta/BaseUserInfoEndpoint.java +++ b/src/main/java/com/authlete/jakarta/BaseUserInfoEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2022 Authlete, Inc. + * Copyright (C) 2016-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.jakarta.UserInfoRequestHandler.Params; import com.authlete.jakarta.spi.UserInfoRequestHandlerSpi; @@ -37,10 +38,9 @@ public class BaseUserInfoEndpoint extends BaseResourceEndpoint { /** - * Handle a userinfo request. - * - * This method is an alias of the {@link #handle(AuthleteApi, - * UserInfoRequestHandlerSpi, UserInfoRequestHandler.Params)} method. + * Handle a userinfo request. This method is an alias of {@link + * #handle(AuthleteApi, UserInfoRequestHandlerSpi, UserInfoRequestHandler.Params) + * handle}{@code (api, spi, accessToken, null, null)}. * * @param api * An implementation of {@link AuthleteApi}. @@ -56,9 +56,44 @@ public class BaseUserInfoEndpoint extends BaseResourceEndpoint */ public Response handle( AuthleteApi api, UserInfoRequestHandlerSpi spi, String accessToken) + { + return handle(api, spi, accessToken, null, null); + } + + + /** + * Handle a userinfo request. This method is an alias of the {@link + * #handle(AuthleteApi, UserInfoRequestHandlerSpi, UserInfoRequestHandler.Params)} + * method. + * + * @param api + * An implementation of {@link AuthleteApi}. + * + * @param spi + * An implementation of {@link UserInfoRequestHandlerSpi}. + * + * @param accessToken + * An access token. + * + * @param userInfoOptions + * The request options for the {@code /api/auth/userinfo} API. + * + * @param userInfoIssueOptions + * The request options for the {@code /api/auth/userinfo/issue} API. + * + * @return + * A response that should be returned to the client application. + * + * @since 2.82 + */ + public Response handle( + AuthleteApi api, UserInfoRequestHandlerSpi spi, String accessToken, + Options userInfoOptions, Options userInfoIssueOptions) { Params params = new Params() .setAccessToken(accessToken) + .setUserInfoOptions(userInfoOptions) + .setUserInfoIssueOptions(userInfoIssueOptions) ; return handle(api, spi, params); @@ -72,7 +107,7 @@ public Response handle( * This method internally creates a {@link UserInfoRequestHandler} instance * and calls its * {@link UserInfoRequestHandler#handle(UserInfoRequestHandler.Params) - * handle(Params)} method. Then, this method uses the value returned from + * handle()} method. Then, this method uses the value returned from * the {@code handle()} method as a response from this method. *

    * diff --git a/src/main/java/com/authlete/jakarta/ClientRegistrationRequestHandler.java b/src/main/java/com/authlete/jakarta/ClientRegistrationRequestHandler.java index 6f514dc..55bb08e 100644 --- a/src/main/java/com/authlete/jakarta/ClientRegistrationRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/ClientRegistrationRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2021 Authlete, Inc. + * Copyright (C) 2019-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.ClientRegistrationResponse; import com.authlete.common.dto.ClientRegistrationResponse.Action; import com.authlete.common.web.BearerToken; @@ -89,7 +90,9 @@ public ClientRegistrationRequestHandler(AuthleteApi api) /** - * Handle a dynamic client registration request. + * Handle a dynamic client registration request. This method is an alias of + * {@link #handleRegister(String, String, Options) handleRegister}{@code + * (json, authorization, null)}. * * @param json * The serialized JSON body of the client registration request. @@ -105,13 +108,40 @@ public ClientRegistrationRequestHandler(AuthleteApi api) * An error occurred. */ public Response handleRegister(String json, String authorization) + { + return handleRegister(json, authorization, null); + } + + + /** + * Handle a dynamic client registration request. + * + * @param json + * The serialized JSON body of the client registration request. + * + * @param authorization + * The value of {@code Authorization} header of the token request. + * This is optional. + * + * @param options + * The request options for the {@code /api/client/registration} API. + * + * @return + * A response that should be returned to the client application. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handleRegister(String json, String authorization, Options options) { String initialAccessToken = BearerToken.parse(authorization); try { ClientRegistrationResponse response = getApiCaller().callClientRegistration( - json, initialAccessToken); + json, initialAccessToken, options); return process(response); } catch (WebApplicationException e) @@ -126,7 +156,8 @@ public Response handleRegister(String json, String authorization) /** - * Handle a dynamic client management GET request. + * Handle a dynamic client management GET request. This method is an alias of + * the {@link #handleGet(String, String, Options) handleGet}{@code (clientId, authorization, null)}. * * @param clientId * The client ID as determined by the incoming request. @@ -142,13 +173,40 @@ public Response handleRegister(String json, String authorization) * An error occurred. */ public Response handleGet(String clientId, String authorization) + { + return handleGet(clientId, authorization, null); + } + + + /** + * Handle a dynamic client management GET request. + * + * @param clientId + * The client ID as determined by the incoming request. + * + * @param authorization + * The value of {@code Authorization} header of the registration request. + * This is optional. + * + * @param options + * The request options for the {@code /api/client/registration} API. + * + * @return + * A response that should be returned to the client application. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handleGet(String clientId, String authorization, Options options) { String registrationAccessToken = BearerToken.parse(authorization); try { ClientRegistrationResponse response = getApiCaller().callClientRegistrationGet( - clientId, registrationAccessToken); + clientId, registrationAccessToken, options); return process(response); } catch (WebApplicationException e) @@ -163,7 +221,9 @@ public Response handleGet(String clientId, String authorization) /** - * Handle a dynamic client management PUT request. + * Handle a dynamic client management PUT request. This method is an alias of + * {@link #handleUpdate(String, String, String, Options) handleUpdate}{@code + * (clientId, json, authorization, null)}. * * @param clientId * The client ID as determined by the incoming request. @@ -182,13 +242,44 @@ public Response handleGet(String clientId, String authorization) * An error occurred. */ public Response handleUpdate(String clientId, String json, String authorization) + { + return handleUpdate(clientId, json, authorization, null); + } + + + /** + * Handle a dynamic client management PUT request. + * + * @param clientId + * The client ID as determined by the incoming request. + * + * @param json + * The serialized JSON body of the client update request. + * + * @param authorization + * The value of {@code Authorization} header of the registration request. + * This is optional. + * + * @param options + * The request options for the {@code /api/client/registration} API. + * + * @return + * A response that should be returned to the client application. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handleUpdate( + String clientId, String json, String authorization, Options options) { String registrationAccessToken = BearerToken.parse(authorization); try { ClientRegistrationResponse response = getApiCaller().callClientRegistrationUpdate( - clientId, json, registrationAccessToken); + clientId, json, registrationAccessToken, options); return process(response); } catch (WebApplicationException e) @@ -203,7 +294,8 @@ public Response handleUpdate(String clientId, String json, String authorization) /** - * Handle a dynamic client management DELETE request. + * Handle a dynamic client management DELETE request. This method is an alias + * of {@link #handleDelete(String, String, Options) handleDelete}{@code (clientId, authorization, null)}. * * @param clientId * The client ID as determined by the incoming request. @@ -219,13 +311,40 @@ public Response handleUpdate(String clientId, String json, String authorization) * An error occurred. */ public Response handleDelete(String clientId, String authorization) + { + return handleDelete(clientId, authorization, null); + } + + + /** + * Handle a dynamic client management DELETE request. + * + * @param clientId + * The client ID as determined by the incoming request. + * + * @param authorization + * The value of {@code Authorization} header of the registration request. + * This is optional. + * + * @param options + * The request options for the {@code /api/client/registration} API. + * + * @return + * A response that should be returned to the client application. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handleDelete(String clientId, String authorization, Options options) { String registrationAccessToken = BearerToken.parse(authorization); try { ClientRegistrationResponse response = getApiCaller().callClientRegistrationDelete( - clientId, registrationAccessToken); + clientId, registrationAccessToken, options); return process(response); } catch (WebApplicationException e) diff --git a/src/main/java/com/authlete/jakarta/ConfigurationRequestHandler.java b/src/main/java/com/authlete/jakarta/ConfigurationRequestHandler.java index 7fd916d..5166a2c 100644 --- a/src/main/java/com/authlete/jakarta/ConfigurationRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/ConfigurationRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2022 Authlete, Inc. + * Copyright (C) 2016-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.ServiceConfigurationRequest; @@ -102,6 +103,48 @@ public Response handle() throws WebApplicationException } + /** + * Handle a request to an OpenID Provider configuration endpoint. This + * method is an alias of {@link #handle(boolean, Options) handle}{@code (true, options)}. + * + * @param options + * The request options to the Authlete API. + * + * @return + * A response that should be returned from the endpoint to + * the client application. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handle(Options options) throws WebApplicationException + { + return handle(true, options); + } + + + /** + * Handle a request to an OpenID Provider configuration endpoint. This + * method is an alias of {@link #handle(boolean, Options) handle}{@code (pretty, null)}. + * + * @param pretty + * {@code true} to return the output JSON in pretty format. + * + * @return + * A response that should be returned from the endpoint to + * the client application. + * + * @throws WebApplicationException + * An error occurred. + */ + public Response handle(boolean pretty) throws WebApplicationException + { + return handle(pretty, null); + } + + /** * Handle a request to an OpenID Provider configuration endpoint. This * method internally calls Authlete's {@code /api/service/configuration} @@ -110,21 +153,26 @@ public Response handle() throws WebApplicationException * @param pretty * {@code true} to return the output JSON in pretty format. * + * @param options + * The request options to the Authlete API. + * * @return * A response that should be returned from the endpoint to * the client application. * * @throws WebApplicationException * An error occurred. + * + * @since 2.82 */ - public Response handle(boolean pretty) throws WebApplicationException + public Response handle(boolean pretty, Options options) throws WebApplicationException { try { // Call Authlete's /api/service/configuration API. // The API returns a JSON that complies with // OpenID Connect Discovery 1.0. - String json = getApiCaller().callServiceConfiguration(pretty); + String json = getApiCaller().callServiceConfiguration(pretty, options); // Response as "application/json;charset=UTF-8" with 200 OK. return ResponseUtil.ok(json); @@ -144,11 +192,11 @@ public Response handle(boolean pretty) throws WebApplicationException /** * Handle a request to an OpenID Provider configuration endpoint. This - * method internally calls Authlete's {@code /api/service/configuration} - * API. + * method is an alias of {@link + * #handle(ServiceConfigurationRequest, Options) handle}{@code (request, null)}. * * @param request - * Request parameters to the Authlete API. + * The request parameters to the Authlete API. * * @return * A response that should be returned from the discovery endpoint. @@ -159,13 +207,39 @@ public Response handle(boolean pretty) throws WebApplicationException * @since 2.50 */ public Response handle(ServiceConfigurationRequest request) throws WebApplicationException + { + return handle(request, null); + } + + + /** + * Handle a request to an OpenID Provider configuration endpoint. This + * method internally calls Authlete's {@code /api/service/configuration} + * API. + * + * @param request + * The request parameters to the Authlete API. + * + * @param options + * The request options to the Authlete API. + * + * @return + * A response that should be returned from the discovery endpoint. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handle( + ServiceConfigurationRequest request, Options options) throws WebApplicationException { try { // Call Authlete's /api/service/configuration API. // The API returns a JSON that complies with // OpenID Connect Discovery 1.0. - String json = getApiCaller().callServiceConfiguration(request); + String json = getApiCaller().callServiceConfiguration(request, options); // Response as "application/json;charset=UTF-8" with 200 OK. return ResponseUtil.ok(json); diff --git a/src/main/java/com/authlete/jakarta/CredentialIssuerMetadataRequestHandler.java b/src/main/java/com/authlete/jakarta/CredentialIssuerMetadataRequestHandler.java index fb17283..4aabb45 100644 --- a/src/main/java/com/authlete/jakarta/CredentialIssuerMetadataRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/CredentialIssuerMetadataRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Authlete, Inc. + * Copyright (C) 2023-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.CredentialIssuerMetadataRequest; import com.authlete.common.dto.CredentialIssuerMetadataResponse; import com.authlete.common.dto.CredentialIssuerMetadataResponse.Action; @@ -53,23 +54,50 @@ public CredentialIssuerMetadataRequestHandler(AuthleteApi api) } + /** + * Handle a request to the credential issuer metadata endpoint. This method + * is an alias of the {@link + * #handle(CredentialIssuerMetadataRequest, Options) handle}{@code (request, null)}. + * + * @param request + * A credential issuer metadata request. + * + * @return + * A response that should be returned from the credential issuer + * metadata endpoint. + * + * @throws WebApplicationException + */ + public Response handle( + CredentialIssuerMetadataRequest request) throws WebApplicationException + { + return handle(request, null); + } + + /** * Handle a request to the credential issuer metadata endpoint. * * @param request * A credential issuer metadata request. * + * @param options + * The request options for the {@code /api/vci/metadata} API. + * * @return * A response that should be returned from the credential issuer * metadata endpoint. * * @throws WebApplicationException + * + * @since 2.82 */ - public Response handle(CredentialIssuerMetadataRequest request) throws WebApplicationException + public Response handle( + CredentialIssuerMetadataRequest request, Options options) throws WebApplicationException { // Call Authlete's /vci/metadata API. CredentialIssuerMetadataResponse response = - getApiCaller().callCredentialIssuerMetadata(request); + getApiCaller().callCredentialIssuerMetadata(request, options); // 'action' in the response denotes the next action which // the implementation of the endpoint should take. diff --git a/src/main/java/com/authlete/jakarta/CredentialJwtIssuerMetadataRequestHandler.java b/src/main/java/com/authlete/jakarta/CredentialJwtIssuerMetadataRequestHandler.java index 9eb0462..be0e0a0 100644 --- a/src/main/java/com/authlete/jakarta/CredentialJwtIssuerMetadataRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/CredentialJwtIssuerMetadataRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Authlete, Inc. + * Copyright (C) 2023-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.CredentialJwtIssuerMetadataRequest; import com.authlete.common.dto.CredentialJwtIssuerMetadataResponse; import com.authlete.common.dto.CredentialJwtIssuerMetadataResponse.Action; @@ -54,7 +55,9 @@ public CredentialJwtIssuerMetadataRequestHandler(AuthleteApi api) /** - * Handle a request to the JWT issuer metadata endpoint. + * Handle a request to the JWT issuer metadata endpoint. This method + * is an alias of {@link #handle(CredentialJwtIssuerMetadataRequest, Options) + * handle}{@code (request, null)}. * * @param request * A JWT issuer metadata request. @@ -66,10 +69,32 @@ public CredentialJwtIssuerMetadataRequestHandler(AuthleteApi api) * @throws WebApplicationException */ public Response handle(CredentialJwtIssuerMetadataRequest request) throws WebApplicationException + { + return handle(request, null); + } + + + /** + * Handle a request to the JWT issuer metadata endpoint. + * + * @param request + * A JWT issuer metadata request. + * + * @param options + * The request options for the {@code /api/vci/jwtissuer} API. + * + * @return + * A response that should be returned from the JWT issuer + * metadata endpoint. + * + * @throws WebApplicationException + */ + public Response handle( + CredentialJwtIssuerMetadataRequest request, Options options) throws WebApplicationException { // Call Authlete's /vci/jwtissuer API. CredentialJwtIssuerMetadataResponse response = - getApiCaller().callCredentialJwtIssuerMetadata(request); + getApiCaller().callCredentialJwtIssuerMetadata(request, options); // 'action' in the response denotes the next action which // the implementation of the endpoint should take. diff --git a/src/main/java/com/authlete/jakarta/CredentialOfferUriRequestHandler.java b/src/main/java/com/authlete/jakarta/CredentialOfferUriRequestHandler.java index ab1cd6b..d422b5d 100644 --- a/src/main/java/com/authlete/jakarta/CredentialOfferUriRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/CredentialOfferUriRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Authlete, Inc. + * Copyright (C) 2023-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.CredentialOfferInfoRequest; import com.authlete.common.dto.CredentialOfferInfoResponse; @@ -33,10 +34,17 @@ public CredentialOfferUriRequestHandler(final AuthleteApi api) public Response handle(final CredentialOfferInfoRequest request) + { + return handle(request, null); + } + + + public Response handle(final CredentialOfferInfoRequest request, Options options) { try { - final CredentialOfferInfoResponse response = getApiCaller().callCredentialOfferInfo(request); + final CredentialOfferInfoResponse response = + getApiCaller().callCredentialOfferInfo(request, options); return process(response); } catch (WebApplicationException e) diff --git a/src/main/java/com/authlete/jakarta/DeviceAuthorizationRequestHandler.java b/src/main/java/com/authlete/jakarta/DeviceAuthorizationRequestHandler.java index 985c6fb..4501694 100644 --- a/src/main/java/com/authlete/jakarta/DeviceAuthorizationRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/DeviceAuthorizationRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Authlete, Inc. + * Copyright (C) 2019-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.DeviceAuthorizationResponse; import com.authlete.common.dto.DeviceAuthorizationResponse.Action; import com.authlete.common.web.BasicCredentials; @@ -65,11 +66,12 @@ public DeviceAuthorizationRequestHandler(AuthleteApi api) /** - * Handler for device authorization requests in OAuth 2.0 Device Authorization - * Grant (Device Flow). + * Handle device authorization requests in OAuth 2.0 Device Authorization Grant + * (Device Flow). This method is an alias of {@link #handle(MultivaluedMap, String, String[], Options) + * handle}{@code (parameters, authorization, clientCertificatePath, null)}. * * @param parameters - * Request parameters of a device authorization request. + * The request parameters of a device authorization request. * * @param authorization * The value of {@code Authorization} header in the device authorization @@ -93,6 +95,45 @@ public DeviceAuthorizationRequestHandler(AuthleteApi api) public Response handle( MultivaluedMap parameters, String authorization, String[] clientCertificatePath) throws WebApplicationException + { + return handle(parameters, authorization, clientCertificatePath, null); + } + + + /** + * Handle device authorization requests in OAuth 2.0 Device Authorization Grant + * (Device Flow). + * + * @param parameters + * The request parameters of a device authorization request. + * + * @param authorization + * The value of {@code Authorization} header in the device authorization + * request. A client application may embed its pair of client ID and + * client secret in a device authorization request using Basic + * Authentication. + * + * @param clientCertificatePath + * The path of the client's certificate, each in PEM format. The first + * item in the array is the client's certificate itself. May be {@code null} + * if the client did not send a certificate or path. + * + * @param options + * The request options for the device authorization request. + * + * @return + * A response that should be returned from the endpoint to the + * client application. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handle( + MultivaluedMap parameters, String authorization, + String[] clientCertificatePath, Options options) throws WebApplicationException { // Convert the value of Authorization header (credentials of // the client application), if any, into BasicCredentials. @@ -106,7 +147,7 @@ public Response handle( try { // Process the given parameters. - return process(parameters, clientId, clientSecret, clientCertificatePath); + return process(parameters, clientId, clientSecret, clientCertificatePath, options); } catch (WebApplicationException e) { @@ -125,7 +166,7 @@ public Response handle( */ private Response process( MultivaluedMap parameters, String clientId, - String clientSecret, String[] clientCertificatePath) + String clientSecret, String[] clientCertificatePath, Options options) { // TODO: Duplicate code. String clientCertificate = null; @@ -144,7 +185,7 @@ private Response process( // Call Authlete's /api/device/authorization API. DeviceAuthorizationResponse response = getApiCaller().callDeviceAuthorization( - parameters, clientId, clientSecret, clientCertificate, clientCertificatePath); + parameters, clientId, clientSecret, clientCertificate, clientCertificatePath, options); // 'action' in the response denotes the next action which // this service implementation should take. diff --git a/src/main/java/com/authlete/jakarta/DeviceCompleteRequestHandler.java b/src/main/java/com/authlete/jakarta/DeviceCompleteRequestHandler.java index e7a9e9f..020669d 100644 --- a/src/main/java/com/authlete/jakarta/DeviceCompleteRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/DeviceCompleteRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 Authlete, Inc. + * Copyright (C) 2019-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.DeviceCompleteRequest; import com.authlete.common.dto.DeviceCompleteRequest.Result; import com.authlete.common.dto.DeviceCompleteResponse; @@ -76,7 +77,8 @@ public DeviceCompleteRequestHandler(AuthleteApi api, DeviceCompleteRequestHandle /** * Handle the result of end-user authentication and authorization in OAuth - * 2.0 Device Authorization Grant (Device Flow). + * 2.0 Device Authorization Grant (Device Flow). This method is an alias of + * {@link #handle(String, String[], Options) handle}{@code (userCode, claimNames, null)}. * * @param userCode * The user code that the end-user input. @@ -93,11 +95,41 @@ public DeviceCompleteRequestHandler(AuthleteApi api, DeviceCompleteRequestHandle * An error occurred. */ public Response handle(String userCode, String[] claimNames) throws WebApplicationException + { + return handle(userCode, claimNames, null); + } + + + /** + * Handle the result of end-user authentication and authorization in OAuth + * 2.0 Device Authorization Grant (Device Flow). + * + * @param userCode + * The user code that the end-user input. + * + * @param claimNames + * Names of requested claims. Use the value of the {@code claimNames} + * parameter in a response from Authlete's {@code /api/device/verification} + * API. + * + * @param options + * The request options for the {@code /api/client/registration} API. + * + * @return + * A response that should be returned to the end-user. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handle( + String userCode, String[] claimNames, Options options) throws WebApplicationException { try { // Process the given parameters. - return process(userCode, claimNames); + return process(userCode, claimNames, options); } catch (WebApplicationException e) { @@ -111,10 +143,10 @@ public Response handle(String userCode, String[] claimNames) throws WebApplicati } - private Response process(String userCode, String[] claimNames) + private Response process(String userCode, String[] claimNames, Options options) { // Call Authlete's /api/device/complete API. - DeviceCompleteResponse response = complete(userCode, claimNames); + DeviceCompleteResponse response = complete(userCode, claimNames, options); // 'action' in the response denotes the next action which // this service implementation should take. @@ -150,7 +182,7 @@ private Response process(String userCode, String[] claimNames) } - private DeviceCompleteResponse complete(String userCode, String[] claimNames) + private DeviceCompleteResponse complete(String userCode, String[] claimNames, Options options) { // Get the result of end-user authentication and authorization. Result result = mSpi.getResult(); @@ -165,7 +197,7 @@ private DeviceCompleteResponse complete(String userCode, String[] claimNames) // The end-user has not successfully authorized the client. // Then, complete the process with failure. - return fail(userCode, result, errorDescription, errorUri); + return fail(userCode, result, errorDescription, errorUri, options); } // OK. The end-user has successfully authorized the client. @@ -192,7 +224,8 @@ private DeviceCompleteResponse complete(String userCode, String[] claimNames) Property[] properties = mSpi.getProperties(); // Complete the process with successful authorization. - return authorize(userCode, subject, authTime, acr, claims, properties, scopes); + return authorize( + userCode, subject, authTime, acr, claims, properties, scopes, options); } @@ -236,30 +269,31 @@ private Map collectClaims(String[] requestedClaimNames) private DeviceCompleteResponse authorize( String userCode, String subject, long authTime, String acr, Map claims, - Property[] properties, String[] scopes) + Property[] properties, String[] scopes, Options options) { return callDeviceComlete( userCode, subject, Result.AUTHORIZED, authTime, acr, claims, - properties, scopes, null, null); + properties, scopes, null, null, options); } private DeviceCompleteResponse fail( - String userCode, Result result, String errorDescription, URI errorUri) + String userCode, Result result, String errorDescription, URI errorUri, + Options options) { return callDeviceComlete( userCode, null, result, 0, null, null, null, null, errorDescription, - errorUri); + errorUri, options); } private DeviceCompleteResponse callDeviceComlete( String userCode, String subject, DeviceCompleteRequest.Result result, long authTime, String acr, Map claims, Property[] properties, - String[] scopes, String errorDescription, URI errorUri) + String[] scopes, String errorDescription, URI errorUri, Options options) { return getApiCaller().callDeviceComplete( userCode, subject, result, authTime, acr, claims, properties, scopes, - errorDescription, errorUri); + errorDescription, errorUri, options); } } diff --git a/src/main/java/com/authlete/jakarta/DeviceVerificationRequestHandler.java b/src/main/java/com/authlete/jakarta/DeviceVerificationRequestHandler.java index 0b4b344..79564c5 100644 --- a/src/main/java/com/authlete/jakarta/DeviceVerificationRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/DeviceVerificationRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 Authlete, Inc. + * Copyright (C) 2019-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.DeviceVerificationResponse; import com.authlete.common.dto.DeviceVerificationResponse.Action; import com.authlete.jakarta.spi.DeviceVerificationRequestHandlerSpi; @@ -71,7 +72,8 @@ public DeviceVerificationRequestHandler(AuthleteApi api, DeviceVerificationReque /** * Handle information associated with a user code that the end-user * input at the verification endpoint in OAuth 2.0 Device Authorization Grant - * (Device Flow). + * (Device Flow). This method is an alias of {@link #handle(Options) handle}{@code + * (null)}. * * @return * A response that should be returned to the end-user. @@ -80,11 +82,31 @@ public DeviceVerificationRequestHandler(AuthleteApi api, DeviceVerificationReque * An error occurred. */ public Response handle() throws WebApplicationException + { + return handle(null); + } + + + /** + * Handle information associated with a user code that the end-user + * input at the verification endpoint in OAuth 2.0 Device Authorization Grant + * (Device Flow). + * + * @param options + * The request options for the {@code /api/device/verification} API. + * + * @return + * A response that should be returned to the end-user. + * + * @throws WebApplicationException + * An error occurred. + */ + public Response handle(Options options) throws WebApplicationException { try { // Process the given parameters. - return process(); + return process(options); } catch (WebApplicationException e) { @@ -98,10 +120,11 @@ public Response handle() throws WebApplicationException } - private Response process() + private Response process(Options options) { // Call Authlete's /api/device/verification API. - DeviceVerificationResponse response = getApiCaller().callDeviceVerification(mSpi.getUserCode()); + DeviceVerificationResponse response = + getApiCaller().callDeviceVerification(mSpi.getUserCode(), options); // 'action' in the response denotes the next action which // this service implementation should take. diff --git a/src/main/java/com/authlete/jakarta/FederationConfigurationRequestHandler.java b/src/main/java/com/authlete/jakarta/FederationConfigurationRequestHandler.java index 941f576..fbf1939 100644 --- a/src/main/java/com/authlete/jakarta/FederationConfigurationRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/FederationConfigurationRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Authlete, Inc. + * Copyright (C) 2022-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.FederationConfigurationRequest; import com.authlete.common.dto.FederationConfigurationResponse; import com.authlete.common.dto.FederationConfigurationResponse.Action; @@ -54,7 +55,9 @@ public FederationConfigurationRequestHandler(AuthleteApi api) /** - * Handle a request to the entity configuration endpoint. + * Handle a request to the entity configuration endpoint. This method is an + * alias of {@link #handle(FederationConfigurationRequest, Options) handle}{@code + * (request, null)}. * * @param request * An entity configuration request. @@ -66,10 +69,34 @@ public FederationConfigurationRequestHandler(AuthleteApi api) * @throws WebApplicationException */ public Response handle(FederationConfigurationRequest request) throws WebApplicationException + { + return handle(request, null); + } + + + /** + * Handle a request to the entity configuration endpoint. + * + * @param request + * An entity configuration request. + * + * @param options + * The request options for the {@code /api/federation/configuration} API. + * + * @return + * A response that should be returned from the entity configuration + * endpoint. + * + * @throws WebApplicationException + * + * @since 2.82 + */ + public Response handle( + FederationConfigurationRequest request, Options options) throws WebApplicationException { // Call Authlete's /api/federation/configuration API. FederationConfigurationResponse response = - getApiCaller().callFederationConfiguration(request); + getApiCaller().callFederationConfiguration(request, options); // 'action' in the response denotes the next action which // the implementation of the endpoint should take. diff --git a/src/main/java/com/authlete/jakarta/FederationRegistrationRequestHandler.java b/src/main/java/com/authlete/jakarta/FederationRegistrationRequestHandler.java index b89161c..b90420e 100644 --- a/src/main/java/com/authlete/jakarta/FederationRegistrationRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/FederationRegistrationRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Authlete, Inc. + * Copyright (C) 2022-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.FederationRegistrationRequest; import com.authlete.common.dto.FederationRegistrationResponse; import com.authlete.common.dto.FederationRegistrationResponse.Action; @@ -54,7 +55,9 @@ public FederationRegistrationRequestHandler(AuthleteApi api) /** - * Handle a request to the federation registration endpoint. + * Handle a request to the federation registration endpoint. This method is + * an alias of {@link #handle(FederationRegistrationRequest, Options) handle}{@code + * (request, null)}. * * @param request * An "explicit" client registration request. @@ -66,10 +69,34 @@ public FederationRegistrationRequestHandler(AuthleteApi api) * @throws WebApplicationException */ public Response handle(FederationRegistrationRequest request) throws WebApplicationException + { + return handle(request, null); + } + + + /** + * Handle a request to the federation registration endpoint. + * + * @param request + * An "explicit" client registration request. + * + * @param options + * The request options for the {@code /api/federation/registration} API. + * + * @return + * A response that should be returned from the federation + * registration endpoint. + * + * @throws WebApplicationException + * + * @since 2.82 + */ + public Response handle( + FederationRegistrationRequest request, Options options) throws WebApplicationException { // Call Authlete's /api/federation/registration API. FederationRegistrationResponse response = - getApiCaller().callFederationRegistration(request); + getApiCaller().callFederationRegistration(request, options); // 'action' in the response denotes the next action which // the implementation of the endpoint should take. diff --git a/src/main/java/com/authlete/jakarta/GMRequestHandler.java b/src/main/java/com/authlete/jakarta/GMRequestHandler.java index cf371e8..4ecb4e1 100644 --- a/src/main/java/com/authlete/jakarta/GMRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/GMRequestHandler.java @@ -22,6 +22,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.GMRequest; import com.authlete.common.dto.GMResponse; import com.authlete.common.dto.GMResponse.Action; @@ -54,7 +55,8 @@ public GMRequestHandler(AuthleteApi api) /** - * Handle a grant management request. + * Handle a grant management request. This method is an alias of {@link + * #handle(GMRequest, Options) handle}{@code (request, null)}. * * @param request * A grant management request. @@ -66,9 +68,33 @@ public GMRequestHandler(AuthleteApi api) * @throws WebApplicationException */ public Response handle(GMRequest request) throws WebApplicationException + { + return handle(request, null); + } + + + /** + * Handle a grant management request. + * + * @param request + * A grant management request. + * + * @param options + * The request options for the {@code /api/gm} API. + * + * @return + * A response that should be returned from the grant management + * endpoint to the client application. + * + * @throws WebApplicationException + * + * @since 2.82 + */ + public Response handle( + GMRequest request, Options options) throws WebApplicationException { // Call Authlete's /api/gm API. - GMResponse response = getApiCaller().callGm(request); + GMResponse response = getApiCaller().callGm(request, options); // 'action' in the response denotes the next action which // the implementation of grant management endpoint should take. diff --git a/src/main/java/com/authlete/jakarta/IntrospectionRequestHandler.java b/src/main/java/com/authlete/jakarta/IntrospectionRequestHandler.java index 5094516..576b42e 100644 --- a/src/main/java/com/authlete/jakarta/IntrospectionRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/IntrospectionRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2023 Authlete, Inc. + * Copyright (C) 2017-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.StandardIntrospectionResponse; import com.authlete.common.dto.StandardIntrospectionResponse.Action; import com.authlete.common.types.JWEAlg; @@ -59,7 +60,7 @@ public class IntrospectionRequestHandler extends BaseHandler */ public static class Params implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 2L; private MultivaluedMap parameters; @@ -72,6 +73,7 @@ public static class Params implements Serializable private String sharedKeyForSign; private String sharedKeyForEncryption; private String publicKeyForEncryption; + private Options options; /** @@ -451,6 +453,39 @@ public Params setPublicKeyForEncryption(String key) return this; } + + + /** + * Get the request options for the {@code /api/auth/introspection} API. + * + * @return + * The request options for the {@code /api/auth/introspection} API. + * + * @since 2.82 + */ + public Options getOptions() + { + return options; + } + + + /** + * Set the request options for the {@code /api/auth/introspection} API. + * + * @param options + * The request options for the {@code /api/auth/introspection} API. + * + * @return + * {@code this} object. + * + * @since 2.82 + */ + public Params setOptions(Options options) + { + this.options = options; + + return this; + } } @@ -468,12 +503,35 @@ public IntrospectionRequestHandler(AuthleteApi api) /** * Handle an introspection request (RFC 7662). + * >RFC 7662). This method is an alias of {@link #handle(MultivaluedMap, Options) + * handle}{@code (parameters, null)}. + * + * @param parameters + * The request parameters of an introspection request. * - * This method is an alias of the {@link #handle(Params)} method. + * @return + * A response that should be returned from the endpoint to + * the resource server. + * + * @throws WebApplicationException + * An error occurred. + */ + public Response handle( + MultivaluedMap parameters) throws WebApplicationException + { + return handle(parameters, null); + } + + + /** + * Handle an introspection request (RFC 7662). This method is an alias of the {@link #handle(Params)} method. * * @param parameters - * Request parameters of an introspection request. + * The request parameters of an introspection request. + * + * @param options + * The request options for the {@code /api/auth/introspection/standard} API. * * @return * A response that should be returned from the endpoint to @@ -481,11 +539,15 @@ public IntrospectionRequestHandler(AuthleteApi api) * * @throws WebApplicationException * An error occurred. + * + * @since 2.82 */ - public Response handle(MultivaluedMap parameters) throws WebApplicationException + public Response handle( + MultivaluedMap parameters, Options options) throws WebApplicationException { Params params = new Params() .setParameters(parameters) + .setOptions(options) ; return handle(params); @@ -524,7 +586,8 @@ public Response handle(Params params) throws WebApplicationException params.getIntrospectionEncryptionEnc(), params.getSharedKeyForSign(), params.getSharedKeyForEncryption(), - params.getPublicKeyForEncryption() + params.getPublicKeyForEncryption(), + params.getOptions() ); } catch (WebApplicationException e) @@ -545,13 +608,13 @@ public Response handle(Params params) throws WebApplicationException private Response process( MultivaluedMap parameters, boolean withHiddenProperties, String httpAcceptHeader, URI rsUri, JWSAlg introspectionSignAlg, JWEAlg introspectionEncAlg, JWEEnc introspectionEncEnc, - String sharedKeyForSign, String sharedKeyForEncryption, String publicKeyForEncryption) + String sharedKeyForSign, String sharedKeyForEncryption, String publicKeyForEncryption, Options options) { // Call Authlete's /api/auth/introspection/standard API. StandardIntrospectionResponse response = getApiCaller().callStandardIntrospection( parameters, withHiddenProperties, httpAcceptHeader, rsUri, introspectionSignAlg, introspectionEncAlg, introspectionEncEnc, sharedKeyForSign, sharedKeyForEncryption, - publicKeyForEncryption); + publicKeyForEncryption, options); // 'action' in the response denotes the next action which // this service implementation should take. diff --git a/src/main/java/com/authlete/jakarta/JwksRequestHandler.java b/src/main/java/com/authlete/jakarta/JwksRequestHandler.java index e241397..48e5c19 100644 --- a/src/main/java/com/authlete/jakarta/JwksRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/JwksRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Authlete, Inc. + * Copyright (C) 2016-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; /** @@ -57,7 +58,7 @@ public JwksRequestHandler(AuthleteApi api) /** * Handle a request to a JWK Set endpoint. This method is an alias - * of {@link #handle(boolean) handle}{@code (true)}. + * of {@link #handle(Options) handle}{@code (null)}. * * @return * A response that should be returned from the endpoint to @@ -68,7 +69,49 @@ public JwksRequestHandler(AuthleteApi api) */ public Response handle() throws WebApplicationException { - return handle(true); + return handle(null); + } + + + /** + * Handle a request to a JWK Set endpoint. This method is an alias + * of {@link #handle(boolean, Options) handle}{@code (true, options)}. + * + * @param options + * The request options for the {@code /api/service/jwks/get} API. + * + * @return + * A response that should be returned from the endpoint to + * the client application. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handle(Options options) throws WebApplicationException + { + return handle(true, options); + } + + + /** + * Handle a request to a JWK Set endpoint. This method is an alias + * of {@link #handle(boolean, Options) handle}{@code (pretty, null)}. + * + * @param pretty + * {@code true} to return the output JSON in pretty format. + * + * @return + * A response that should be returned from the endpoint to + * the client application. + * + * @throws WebApplicationException + * An error occurred. + */ + public Response handle(boolean pretty) throws WebApplicationException + { + return handle(pretty, null); } @@ -79,20 +122,25 @@ public Response handle() throws WebApplicationException * @param pretty * {@code true} to return the output JSON in pretty format. * + * @param options + * The request options for the {@code /api/service/jwks/get} API. + * * @return * A response that should be returned from the endpoint to * the client application. * * @throws WebApplicationException * An error occurred. + * + * @since 2.82 */ - public Response handle(boolean pretty) throws WebApplicationException + public Response handle(boolean pretty, Options options) throws WebApplicationException { try { // Call Authlete's /api/service/jwks/get API. It returns the JWK Set // of the service. Of course, private keys are not included. - return getApiCaller().serviceJwksGet(pretty, false); + return getApiCaller().serviceJwksGet(pretty, false, options); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/PushedAuthReqHandler.java b/src/main/java/com/authlete/jakarta/PushedAuthReqHandler.java index 4afa3d8..e534fc5 100644 --- a/src/main/java/com/authlete/jakarta/PushedAuthReqHandler.java +++ b/src/main/java/com/authlete/jakarta/PushedAuthReqHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2023 Authlete, Inc. + * Copyright (C) 2019-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.PushedAuthReqResponse; import com.authlete.common.dto.PushedAuthReqResponse.Action; import com.authlete.common.web.BasicCredentials; @@ -59,7 +60,7 @@ public class PushedAuthReqHandler extends BaseHandler */ public static class Params implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 2L; private MultivaluedMap parameters; @@ -68,6 +69,7 @@ public static class Params implements Serializable private String dpop; private String htm; private String htu; + private Options options; /** @@ -294,6 +296,39 @@ public Params setHtu(String htu) return this; } + + + /** + * Get the request options for the {@code /api/pushed_auth_req} API. + * + * @return + * The request options for the {@code /api/pushed_auth_req} API. + * + * @since 2.82 + */ + public Options getOptions() + { + return options; + } + + + /** + * Set the request options for the {@code /api/pushed_auth_req} API. + * + * @param options + * The request options for the {@code /api/pushed_auth_req} API. + * + * @return + * {@code this} object. + * + * @since 2.82 + */ + public Params setOptions(Options options) + { + this.options = options; + + return this; + } } @@ -310,22 +345,24 @@ public PushedAuthReqHandler(AuthleteApi api) /** - * Handle a pushed authorization request. + * Handle a pushed authorization request. This method is an alias + * of {@link #handle(MultivaluedMap, String, String[], Options) handle}{@code + * (parameters, authorization, clientCertificatePath, null)}. * * @param parameters - * Request parameters of a pushed authorization request. + * The request parameters of a pushed authorization request. * * @param authorization - * The value of {@code Authorization} header in the pushed - * authorization request. A client application may embed its - * pair of client ID and client secret in a pushed authorization - * request using Basic Authentication. + * The value of {@code Authorization} header in the pushed + * authorization request. A client application may embed its + * pair of client ID and client secret in a pushed authorization + * request using Basic Authentication. * * @param clientCertificatePath - * The path of the client's certificate, each in PEM format. - * The first item in the array is the client's certificate itself. - * May be {@code null} if the client did not send a certificate or path. + * The path of the client's certificate, each in PEM format. + * The first item in the array is the client's certificate itself. + * May be {@code null} if the client did not send a certificate or path. * * @return * A response that should be returned from the endpoint to the @@ -337,11 +374,51 @@ public PushedAuthReqHandler(AuthleteApi api) public Response handle( MultivaluedMap parameters, String authorization, String[] clientCertificatePath) throws WebApplicationException + { + return handle(parameters, authorization, clientCertificatePath, null); + } + + + /** + * Handle a pushed authorization request. This method is an alias of the {@link + * #handle(Params)} method. + * + * @param parameters + * The request parameters of a pushed authorization request. + * + * @param authorization + * The value of {@code Authorization} header in the pushed + * authorization request. A client application may embed its + * pair of client ID and client secret in a pushed authorization + * request using Basic Authentication. + * + * @param clientCertificatePath + * The path of the client's certificate, each in PEM format. + * The first item in the array is the client's certificate itself. + * May be {@code null} if the client did not send a certificate or path. + * + * @param options + * The request options for the {@code /api/pushed_auth_req} API. + * + * @return + * A response that should be returned from the endpoint to the + * client application. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handle( + MultivaluedMap parameters, String authorization, + String[] clientCertificatePath, Options options) throws WebApplicationException { Params params = new Params() .setParameters(parameters) .setAuthorization(authorization) .setClientCertificatePath(clientCertificatePath) + .setOptions(options) ; return handle(params); @@ -385,7 +462,8 @@ public Response handle(Params params) params.getClientCertificatePath(), params.getDpop(), params.getHtm(), - params.getHtu() + params.getHtu(), + params.getOptions() ); } catch (WebApplicationException e) @@ -406,7 +484,7 @@ public Response handle(Params params) private Response process( MultivaluedMap parameters, String clientId, String clientSecret, String[] clientCertificatePath, - String dpop, String htm, String htu) + String dpop, String htm, String htu, Options options) { String clientCertificate = null; if (clientCertificatePath != null && clientCertificatePath.length > 0) @@ -424,7 +502,7 @@ private Response process( PushedAuthReqResponse response = getApiCaller().callPushedAuthReq( parameters, clientId, clientSecret, - clientCertificate, clientCertificatePath, dpop, htm, htu); + clientCertificate, clientCertificatePath, dpop, htm, htu, options); // 'action' in the response denotes the next action which // this service implementation should take. diff --git a/src/main/java/com/authlete/jakarta/RevocationRequestHandler.java b/src/main/java/com/authlete/jakarta/RevocationRequestHandler.java index c804b47..e576ef0 100644 --- a/src/main/java/com/authlete/jakarta/RevocationRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/RevocationRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2016 Authlete, Inc. + * Copyright (C) 2015-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.RevocationResponse; import com.authlete.common.dto.RevocationResponse.Action; import com.authlete.common.web.BasicCredentials; @@ -62,12 +63,41 @@ public RevocationRequestHandler(AuthleteApi api) } + /** + * Handle a token revocation request (RFC 7009). This method is an alias of {@link #handle(MultivaluedMap, String, Options) + * handle}{@code (parameters, authorization, null)}. + * + * @param parameters + * The request parameters of a token revocation request. + * + * @param authorization + * The value of {@code Authorization} header in the token revocation + * request. A client application may embed its pair of client ID and + * client secret in a token revocation request using Basic + * Authentication. + * + * @return + * A response that should be returned from the endpoint to the + * client application. + * + * @throws WebApplicationException + * An error occurred. + */ + public Response handle( + MultivaluedMap parameters, String authorization) throws WebApplicationException + { + return handle(parameters, authorization, null); + } + + /** * Handle a token revocation request (RFC 7009). * * @param parameters - * Request parameters of a token revocation request. + * The request parameters of a token revocation request. * * @param authorization * The value of {@code Authorization} header in the token revocation @@ -76,14 +106,21 @@ public RevocationRequestHandler(AuthleteApi api) * "https://tools.ietf.org/html/rfc2617#section-2">Basic * Authentication. * + * @param options + * The request options for the {@code /api/auth/revocation} API. + * * @return * A response that should be returned from the endpoint to the * client application. * * @throws WebApplicationException * An error occurred. + * + * @since 2.82 */ - public Response handle(MultivaluedMap parameters, String authorization) throws WebApplicationException + public Response handle( + MultivaluedMap parameters, String authorization, + Options options) throws WebApplicationException { // Convert the value of Authorization header (credentials of // the client application), if any, into BasicCredentials. @@ -97,7 +134,7 @@ public Response handle(MultivaluedMap parameters, String authori try { // Process the given parameters. - return process(parameters, clientId, clientSecret); + return process(parameters, clientId, clientSecret, options); } catch (WebApplicationException e) { @@ -114,10 +151,12 @@ public Response handle(MultivaluedMap parameters, String authori /** * Process the parameters of the revocation request. */ - private Response process(MultivaluedMap parameters, String clientId, String clientSecret) + private Response process( + MultivaluedMap parameters, String clientId, String clientSecret, Options options) { // Call Authlete's /api/auth/revocation API. - RevocationResponse response = getApiCaller().callRevocation(parameters, clientId, clientSecret); + RevocationResponse response = getApiCaller() + .callRevocation(parameters, clientId, clientSecret, options); // 'action' in the response denotes the next action which // this service implementation should take. diff --git a/src/main/java/com/authlete/jakarta/TokenRequestHandler.java b/src/main/java/com/authlete/jakarta/TokenRequestHandler.java index 9823d4b..43f42ac 100644 --- a/src/main/java/com/authlete/jakarta/TokenRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/TokenRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2023 Authlete, Inc. + * Copyright (C) 2015-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.dto.Property; import com.authlete.common.dto.TokenFailRequest.Reason; import com.authlete.common.dto.TokenResponse; @@ -59,7 +60,7 @@ public class TokenRequestHandler extends BaseHandler */ public static class Params implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 2L; private MultivaluedMap parameters; @@ -68,6 +69,9 @@ public static class Params implements Serializable private String dpop; private String htm; private String htu; + private Options tokenOptions; + private Options tokenIssueOptions; + private Options tokenFailOptions; /** @@ -288,6 +292,105 @@ public Params setHtu(String htu) return this; } + + + /** + * Get the request options for the {@code /api/auth/token} API. + * + * @return + * The request options for the {@code /api/auth/token} API. + * + * @since 2.82 + */ + public Options getTokenOptions() + { + return tokenOptions; + } + + + /** + * Set the request options for the {@code /api/auth/token} API. + * + * @param options + * The request options for the {@code /api/auth/token} API. + * + * @return + * {@code this} object. + * + * @since 2.82 + */ + public Params setTokenOptions(Options options) + { + tokenOptions = options; + + return this; + } + + + /** + * Get the request options for the {@code /api/auth/token/issue} API. + * + * @return + * The request options for the {@code /api/auth/token/issue} API. + * + * @since 2.82 + */ + public Options getTokenIssueOptions() + { + return tokenIssueOptions; + } + + + /** + * Set the request options for the {@code /api/auth/token/issue} API. + * + * @param options + * The request options for the {@code /api/auth/token/issue} API. + * + * @return + * {@code this} object. + * + * @since 2.82 + */ + public Params setTokenIssueOptions(Options options) + { + tokenIssueOptions = options; + + return this; + } + + + /** + * Get the request options for the {@code /api/auth/token/fail} API. + * + * @return + * The request options for the {@code /api/auth/token/fail} API. + * + * @since 2.82 + */ + public Options getTokenFailOptions() + { + return tokenFailOptions; + } + + + /** + * Set the request options for the {@code /api/auth/token/fail} API. + * + * @param options + * The request options for the {@code /api/auth/token/fail} API. + * + * @return + * {@code this} object. + * + * @since 2.82 + */ + public Params setTokenFailOptions(Options options) + { + tokenFailOptions = options; + + return this; + } } @@ -322,12 +425,12 @@ public TokenRequestHandler(AuthleteApi api, TokenRequestHandlerSpi spi) /** - * Handle a token request. - * - * This method is an alias of the {@link #handle(Params)} method. + * Handle a token request. This method is an alias of {@link + * #handle(MultivaluedMap, String, Options, Options, Options) handle}{@code + * (parameters, authorization, null, null, null)}. * * @param parameters - * Request parameters of a token request. + * The request parameters of a token request. * * @param authorization * The value of {@code Authorization} header in the token request. @@ -346,22 +449,59 @@ public TokenRequestHandler(AuthleteApi api, TokenRequestHandlerSpi spi) public Response handle( MultivaluedMap parameters, String authorization) throws WebApplicationException { - Params params = new Params() - .setParameters(parameters) - .setAuthorization(authorization) - ; - - return handle(params); + return handle(parameters, authorization, null, null, null); } /** - * Handle a token request. + * Handle a token request. This method is an alias of {@link + * #handle(MultivaluedMap, String, String[], Options, Options, Options) handle}{@code + * (parameters, authorization, null, tokenOptions, tokenIssueOptions, tokenFailOptions)}. + * + * @param parameters + * The request parameters of a token request. + * + * @param authorization + * The value of {@code Authorization} header in the token request. + * A client application may embed its pair of client ID and client + * secret in a token request using Basic + * Authentication. + * + * @param tokenOptions + * The request options for the {@code /api/auth/token} API. * - * This method is an alias of the {@link #handle(Params)} method. + * @param tokenIssueOptions + * The request options for the {@code /api/auth/token/issue} API. + * + * @param tokenFailOptions + * The request options for the {@code /api/auth/token/fail} API. + * + * @return + * A response that should be returned from the endpoint to the + * client application. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handle( + MultivaluedMap parameters, String authorization, + Options tokenOptions, Options tokenIssueOptions, Options tokenFailOptions) + throws WebApplicationException + { + return handle(parameters, authorization, null, tokenOptions, tokenIssueOptions, tokenFailOptions); + } + + + /** + * Handle a token request. This method is an alias of {@link + * #handle(MultivaluedMap, String, String[], Options, Options, Options) handle}{@code + * (parameters, authorization, clientCertificatePath, null, null, null)}. * * @param parameters - * Request parameters of a token request. + * The request parameters of a token request. * * @param authorization * The value of {@code Authorization} header in the token request. @@ -387,11 +527,60 @@ public Response handle( public Response handle( MultivaluedMap parameters, String authorization, String[] clientCertificatePath) throws WebApplicationException + { + return handle(parameters, authorization, clientCertificatePath, null, null, null); + } + + + /** + * Handle a token request. This method is an alias of the {@link #handle(Params)} + * method. + * + * @param parameters + * The request parameters of a token request. + * + * @param authorization + * The value of {@code Authorization} header in the token request. + * A client application may embed its pair of client ID and client + * secret in a token request using Basic + * Authentication. + * + * @param clientCertificatePath + * The path of the client's certificate, each in PEM format. The first + * item in the array is the client's certificate itself. May be {@code null} if + * the client did not send a certificate or path. + * + * @param tokenOptions + * The request options for the {@code /api/auth/token} API. + * + * @param tokenIssueOptions + * The request options for the {@code /api/auth/token/issue} API. + * + * @param tokenFailOptions + * The request options for the {@code /api/auth/token/fail} API. + * + * @return + * A response that should be returned from the endpoint to the + * client application. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handle( + MultivaluedMap parameters, String authorization, + String[] clientCertificatePath, Options tokenOptions, Options tokenIssueOptions, + Options tokenFailOptions) throws WebApplicationException { Params params = new Params() .setParameters(parameters) .setAuthorization(authorization) .setClientCertificatePath(clientCertificatePath) + .setTokenOptions(tokenFailOptions) + .setTokenIssueOptions(tokenFailOptions) + .setTokenFailOptions(tokenFailOptions) ; return handle(params); @@ -435,7 +624,10 @@ public Response handle(Params params) throws WebApplicationException params.getClientCertificatePath(), params.getDpop(), params.getHtm(), - params.getHtu() + params.getHtu(), + params.getTokenOptions(), + params.getTokenIssueOptions(), + params.getTokenFailOptions() ); } catch (WebApplicationException e) @@ -456,7 +648,8 @@ public Response handle(Params params) throws WebApplicationException private Response process( MultivaluedMap parameters, String clientId, String clientSecret, String[] clientCertificatePath, - String dpop, String htm, String htu) + String dpop, String htm, String htu, Options tokenOptions, Options tokenIssueOptions, + Options tokenFailOptions) { // Extra properties to associate with an access token. Property[] properties = mSpi.getProperties(); @@ -478,7 +671,7 @@ private Response process( // Call Authlete's /api/auth/token API. TokenResponse response = getApiCaller().callToken( parameters, clientId, clientSecret, properties, - clientCertificate, clientCertificatePath, dpop, htm, htu); + clientCertificate, clientCertificatePath, dpop, htm, htu, tokenOptions); // 'action' in the response denotes the next action which // this service implementation should take. @@ -507,7 +700,7 @@ private Response process( case PASSWORD: // Process the token request whose flow is "Resource Owner Password Credentials". - return handlePassword(response, headers); + return handlePassword(response, headers, tokenIssueOptions, tokenFailOptions); case OK: // 200 OK @@ -552,7 +745,9 @@ private static Map prepareHeaders(TokenResponse response) /** * Process the token request whose flow is "Resource Owner Password Credentials". */ - private Response handlePassword(TokenResponse response, Map headers) + private Response handlePassword( + TokenResponse response, Map headers, Options tokenIssueOptions, + Options tokenFailOptions) { // The credentials of the resource owner. String username = response.getUsername(); @@ -571,13 +766,14 @@ private Response handlePassword(TokenResponse response, Map head { // Issue an access token and optionally an ID token. return getApiCaller().tokenIssue( - ticket, subject, properties, headers); + ticket, subject, properties, headers, tokenIssueOptions); } else { // The credentials are invalid. An access token is not issued. throw getApiCaller().tokenFail( - ticket, Reason.INVALID_RESOURCE_OWNER_CREDENTIALS, headers); + ticket, Reason.INVALID_RESOURCE_OWNER_CREDENTIALS, headers, + tokenFailOptions); } } diff --git a/src/main/java/com/authlete/jakarta/UserInfoRequestHandler.java b/src/main/java/com/authlete/jakarta/UserInfoRequestHandler.java index f338b57..20db8d8 100644 --- a/src/main/java/com/authlete/jakarta/UserInfoRequestHandler.java +++ b/src/main/java/com/authlete/jakarta/UserInfoRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2023 Authlete, Inc. + * Copyright (C) 2016-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; import com.authlete.common.api.AuthleteApi; +import com.authlete.common.api.Options; import com.authlete.common.assurance.VerifiedClaims; import com.authlete.common.assurance.constraint.VerifiedClaimsConstraint; import com.authlete.common.assurance.constraint.VerifiedClaimsContainerConstraint; @@ -62,7 +63,7 @@ public class UserInfoRequestHandler extends BaseHandler */ public static class Params implements Serializable { - private static final long serialVersionUID = 2L; + private static final long serialVersionUID = 3L; private String accessToken; @@ -71,6 +72,8 @@ public static class Params implements Serializable private String htm; private String htu; private boolean oldIdaFormatUsed; + private Options userInfoOptions; + private Options userInfoIssueOptions; /** @@ -380,6 +383,72 @@ public Params setOldIdaFormatUsed(boolean used) return this; } + + + /** + * Get the request options for the {@code /api/auth/userinfo} API. + * + * @return + * The request options for the {@code /api/auth/userinfo} API. + * + * @since 2.82 + */ + public Options getUserInfoOptions() + { + return userInfoOptions; + } + + + /** + * Set the request options for the {@code /api/auth/userinfo} API. + * + * @param options + * The request options for the {@code /api/auth/userinfo} API. + * + * @return + * {@code this} object. + * + * @since 2.82 + */ + public Params setUserInfoOptions(Options options) + { + userInfoOptions = options; + + return this; + } + + + /** + * Get the request options for the {@code /api/auth/userinfo/issue} API. + * + * @return + * The request options for the {@code /api/auth/userinfo/issue} API. + * + * @since 2.82 + */ + public Options getUserInfoIssueOptions() + { + return userInfoIssueOptions; + } + + + /** + * Set the request options for the {@code /api/auth/userinfo/issue} API. + * + * @param options + * The request options for the {@code /api/auth/userinfo/issue} API. + * + * @return + * {@code this} object. + * + * @since 2.82 + */ + public Params setUserInfoIssueOptions(Options options) + { + userInfoIssueOptions = options; + + return this; + } } @@ -418,7 +487,8 @@ public UserInfoRequestHandler(AuthleteApi api, UserInfoRequestHandlerSpi spi) * "http://openid.net/specs/openid-connect-core-1_0.html#UserInfo" * >UserInfo Endpoint defined in OpenID Connect - * Core 1.0. + * Core 1.0. This method is an alias of {@link #handle(String, Options, Options) + * handle}{@code (accessToken, null, null)}. * * @param accessToken * An access token. @@ -431,9 +501,45 @@ public UserInfoRequestHandler(AuthleteApi api, UserInfoRequestHandlerSpi spi) * An error occurred. */ public Response handle(String accessToken) throws WebApplicationException + { + return handle(accessToken, null, null); + } + + + /** + * Handle a userinfo request to a UserInfo Endpoint defined in OpenID Connect + * Core 1.0. This method is an alias of the {@link #handle(Params)} + * method. + * + * @param accessToken + * An access token. + * + * @param userInfoOptions + * The request options for the {@code /api/auth/userinfo} API. + * + * @param userInfoIssueOptions + * The request options for the {@code /api/auth/userinfo/issue} API. + * + * @return + * A response that should be returned from the endpoint to the + * client application. + * + * @throws WebApplicationException + * An error occurred. + * + * @since 2.82 + */ + public Response handle( + String accessToken, Options userInfoOptions, Options userInfoIssueOptions) + throws WebApplicationException { Params params = new Params() .setAccessToken(accessToken) + .setUserInfoOptions(userInfoOptions) + .setUserInfoIssueOptions(userInfoIssueOptions) ; return handle(params); @@ -441,7 +547,11 @@ public Response handle(String accessToken) throws WebApplicationException /** - * Handle a userinfo request. + * Handle a userinfo request to a UserInfo Endpoint defined in OpenID Connect + * Core 1.0. * * @param params * Parameters needed to handle the userinfo request. @@ -491,7 +601,8 @@ private Response process(Params params) params.getClientCertificate(), params.getDpop(), params.getHtm(), - params.getHtu() + params.getHtu(), + params.getUserInfoOptions() ); // 'action' in the response denotes the next action which @@ -525,7 +636,7 @@ private Response process(Params params) case OK: // Return the user information. - return getUserInfo(params, response, headers); + return getUserInfo(params, response, headers, params.getUserInfoIssueOptions()); default: // This never happens. @@ -554,7 +665,8 @@ private static Map prepareHeaders(UserInfoResponse response) * Authlete's {@code /api/auth/userinfo/issue} API. */ private Response getUserInfo( - Params params, UserInfoResponse response, Map headers) + Params params, UserInfoResponse response, Map headers, + Options options) { String subject = response.getSubject(); @@ -592,7 +704,7 @@ private Response getUserInfo( // Generate a JSON or a JWT containing user information // by calling Authlete's /api/auth/userinfo/issue API. return getApiCaller().userInfoIssue( - response.getToken(), claims, claimsForTx, verifiedClaimsForTx, headers); + response.getToken(), claims, claimsForTx, verifiedClaimsForTx, headers, options); } catch (WebApplicationException e) { diff --git a/src/main/java/com/authlete/jakarta/api/AuthleteApiImpl.java b/src/main/java/com/authlete/jakarta/api/AuthleteApiImpl.java index 966e18a..ba702f2 100644 --- a/src/main/java/com/authlete/jakarta/api/AuthleteApiImpl.java +++ b/src/main/java/com/authlete/jakarta/api/AuthleteApiImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2023 Authlete, Inc. + * Copyright (C) 2014-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,10 +21,12 @@ import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import java.util.LinkedHashMap; import java.util.Map; +import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.client.WebTarget; import jakarta.ws.rs.core.GenericType; import com.authlete.common.api.AuthleteApi; import com.authlete.common.api.AuthleteApiException; +import com.authlete.common.api.Options; import com.authlete.common.conf.AuthleteApiVersion; import com.authlete.common.conf.AuthleteConfiguration; import com.authlete.common.dto.*; @@ -202,40 +204,40 @@ private String createServiceCredentials(AuthleteConfiguration configuration) private TResponse callServiceOwnerGetApi( - String path, Class responseClass, Map params) + String path, Class responseClass, Map params, Options options) { - return callGetApi(mServiceOwnerAuth, path, responseClass, params); + return callGetApi(mServiceOwnerAuth, path, responseClass, params, options); } private TResponse callServiceGetApi( - String path, Class responseClass, Map params) + String path, Class responseClass, Map params, Options options) { - return callGetApi(mServiceAuth, path, responseClass, params); + return callGetApi(mServiceAuth, path, responseClass, params, options); } - private Void callServiceOwnerDeleteApi(String path) + private Void callServiceOwnerDeleteApi(String path, Options options) { - return callDeleteApi(mServiceOwnerAuth, path); + return callDeleteApi(mServiceOwnerAuth, path, options); } - private Void callServiceDeleteApi(String path) + private Void callServiceDeleteApi(String path, Options options) { - return callDeleteApi(mServiceAuth, path); + return callDeleteApi(mServiceAuth, path, options); } - private TResponse callServiceOwnerPostApi(String path, Object request, Class responseClass) + private TResponse callServiceOwnerPostApi(String path, Object request, Class responseClass, Options options) { - return callPostApi(mServiceOwnerAuth, path, request, responseClass); + return callPostApi(mServiceOwnerAuth, path, request, responseClass, options); } - private TResponse callServicePostApi(String path, Object request, Class responseClass) + private TResponse callServicePostApi(String path, Object request, Class responseClass, Options options) { - return callPostApi(mServiceAuth, path, request, responseClass); + return callPostApi(mServiceAuth, path, request, responseClass, options); } @@ -245,6 +247,7 @@ private static abstract class ApiCaller implements AuthleteApiCall mResponseClass; protected final Map mParams = new LinkedHashMap<>(); + protected Options mOptions; ApiCaller(Class responseClass, Object request, String path) @@ -267,6 +270,14 @@ public ApiCaller addParam(String name, Object... values) return this; } + + + public ApiCaller setOptions(Options options) + { + mOptions = options; + + return this; + } } @@ -287,7 +298,7 @@ private class ServiceOwnerDeleteApiCaller extends ApiCaller @Override public Void call() { - return callServiceOwnerDeleteApi(mPath); + return callServiceOwnerDeleteApi(mPath, mOptions); } } @@ -309,7 +320,7 @@ private class ServiceOwnerGetApiCaller extends ApiCaller @Override public TResponse call() { - return callServiceOwnerGetApi(mPath, mResponseClass, mParams); + return callServiceOwnerGetApi(mPath, mResponseClass, mParams, mOptions); } } @@ -331,7 +342,7 @@ private class ServiceOwnerPostApiCaller extends ApiCaller @Override public TResponse call() { - return callServiceOwnerPostApi(mPath, mRequest, mResponseClass); + return callServiceOwnerPostApi(mPath, mRequest, mResponseClass, mOptions); } } @@ -353,7 +364,7 @@ private class ServiceDeleteApiCaller extends ApiCaller @Override public Void call() { - return callServiceDeleteApi(mPath); + return callServiceDeleteApi(mPath, mOptions); } } @@ -375,7 +386,7 @@ private class ServiceGetApiCaller extends ApiCaller @Override public TResponse call() { - return callServiceGetApi(mPath, mResponseClass, mParams); + return callServiceGetApi(mPath, mResponseClass, mParams, mOptions); } } @@ -397,7 +408,7 @@ private class ServicePostApiCaller extends ApiCaller @Override public TResponse call() { - return callServicePostApi(mPath, mRequest, mResponseClass); + return callServicePostApi(mPath, mRequest, mResponseClass, mOptions); } } @@ -406,11 +417,12 @@ public TResponse call() * Call {@code /api/auth/authorization} API. */ @Override - public AuthorizationResponse authorization(AuthorizationRequest request) throws AuthleteApiException + public AuthorizationResponse authorization(AuthorizationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - AuthorizationResponse.class, request, AUTH_AUTHORIZATION_API_PATH)); + AuthorizationResponse.class, request, AUTH_AUTHORIZATION_API_PATH) + .setOptions(options)); } @@ -418,11 +430,12 @@ public AuthorizationResponse authorization(AuthorizationRequest request) throws * Call {@code /api/auth/authorization/fail} API. */ @Override - public AuthorizationFailResponse authorizationFail(AuthorizationFailRequest request) throws AuthleteApiException + public AuthorizationFailResponse authorizationFail(AuthorizationFailRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - AuthorizationFailResponse.class, request, AUTH_AUTHORIZATION_FAIL_API_PATH)); + AuthorizationFailResponse.class, request, AUTH_AUTHORIZATION_FAIL_API_PATH) + .setOptions(options)); } @@ -430,11 +443,12 @@ public AuthorizationFailResponse authorizationFail(AuthorizationFailRequest requ * Call {@code /api/auth/authorization/issue} API. */ @Override - public AuthorizationIssueResponse authorizationIssue(AuthorizationIssueRequest request) throws AuthleteApiException + public AuthorizationIssueResponse authorizationIssue(AuthorizationIssueRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - AuthorizationIssueResponse.class, request, AUTH_AUTHORIZATION_ISSUE_API_PATH)); + AuthorizationIssueResponse.class, request, AUTH_AUTHORIZATION_ISSUE_API_PATH) + .setOptions(options)); } @@ -442,11 +456,12 @@ public AuthorizationIssueResponse authorizationIssue(AuthorizationIssueRequest r * Call {@code /api/auth/token} API. */ @Override - public TokenResponse token(TokenRequest request) throws AuthleteApiException + public TokenResponse token(TokenRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - TokenResponse.class, request, AUTH_TOKEN_API_PATH)); + TokenResponse.class, request, AUTH_TOKEN_API_PATH) + .setOptions(options)); } @@ -454,11 +469,12 @@ public TokenResponse token(TokenRequest request) throws AuthleteApiException * Call {@code /api/auth/token/create} API. */ @Override - public TokenCreateResponse tokenCreate(TokenCreateRequest request) throws AuthleteApiException + public TokenCreateResponse tokenCreate(TokenCreateRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - TokenCreateResponse.class, request, AUTH_TOKEN_CREATE_API_PATH)); + TokenCreateResponse.class, request, AUTH_TOKEN_CREATE_API_PATH) + .setOptions(options)); } @@ -466,11 +482,12 @@ public TokenCreateResponse tokenCreate(TokenCreateRequest request) throws Authle * Call /api/auth/token/delete/{token} API. */ @Override - public void tokenDelete(String token) throws AuthleteApiException + public void tokenDelete(String token, Options options) throws AuthleteApiException { executeApiCall( new ServiceDeleteApiCaller( - AUTH_TOKEN_DELETE_API_PATH, token)); + AUTH_TOKEN_DELETE_API_PATH, token) + .setOptions(options)); } @@ -478,11 +495,12 @@ public void tokenDelete(String token) throws AuthleteApiException * Call {@code /api/auth/token/fail} API. */ @Override - public TokenFailResponse tokenFail(TokenFailRequest request) throws AuthleteApiException + public TokenFailResponse tokenFail(TokenFailRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - TokenFailResponse.class, request, AUTH_TOKEN_FAIL_API_PATH)); + TokenFailResponse.class, request, AUTH_TOKEN_FAIL_API_PATH) + .setOptions(options)); } @@ -490,11 +508,12 @@ public TokenFailResponse tokenFail(TokenFailRequest request) throws AuthleteApiE * Call {@code /api/auth/token/issue} API. */ @Override - public TokenIssueResponse tokenIssue(TokenIssueRequest request) throws AuthleteApiException + public TokenIssueResponse tokenIssue(TokenIssueRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - TokenIssueResponse.class, request, AUTH_TOKEN_ISSUE_API_PATH)); + TokenIssueResponse.class, request, AUTH_TOKEN_ISSUE_API_PATH) + .setOptions(options)); } @@ -502,11 +521,12 @@ public TokenIssueResponse tokenIssue(TokenIssueRequest request) throws AuthleteA * Call {@code /api/auth/token/revoke} API. */ @Override - public TokenRevokeResponse tokenRevoke(TokenRevokeRequest request) throws AuthleteApiException + public TokenRevokeResponse tokenRevoke(TokenRevokeRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - TokenRevokeResponse.class, request, AUTH_TOKEN_REVOKE_API_PATH)); + TokenRevokeResponse.class, request, AUTH_TOKEN_REVOKE_API_PATH) + .setOptions(options)); } @@ -514,87 +534,88 @@ public TokenRevokeResponse tokenRevoke(TokenRevokeRequest request) throws Authle * Call {@code /api/auth/token/update} API. */ @Override - public TokenUpdateResponse tokenUpdate(TokenUpdateRequest request) throws AuthleteApiException + public TokenUpdateResponse tokenUpdate(TokenUpdateRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - TokenUpdateResponse.class, request, AUTH_TOKEN_UPDATE_API_PATH)); + TokenUpdateResponse.class, request, AUTH_TOKEN_UPDATE_API_PATH) + .setOptions(options)); } @Override - public TokenListResponse getTokenList() throws AuthleteApiException + public TokenListResponse getTokenList(Options options) throws AuthleteApiException { - return getTokenList(null, null, 0, 0, false, TokenStatus.ALL); + return getTokenList(null, null, 0, 0, false, TokenStatus.ALL, options); } @Override - public TokenListResponse getTokenList(TokenStatus tokenStatus) throws AuthleteApiException + public TokenListResponse getTokenList(TokenStatus tokenStatus, Options options) throws AuthleteApiException { - return getTokenList(null, null, 0, 0, false, tokenStatus); + return getTokenList(null, null, 0, 0, false, tokenStatus, options); } @Override - public TokenListResponse getTokenList(String clientIdentifier, String subject) throws AuthleteApiException + public TokenListResponse getTokenList(String clientIdentifier, String subject, Options options) throws AuthleteApiException { - return getTokenList(clientIdentifier, subject, 0, 0, false, TokenStatus.ALL); + return getTokenList(clientIdentifier, subject, 0, 0, false, TokenStatus.ALL, options); } @Override - public TokenListResponse getTokenList(String clientIdentifier, String subject, TokenStatus tokenStatus) throws AuthleteApiException + public TokenListResponse getTokenList(String clientIdentifier, String subject, TokenStatus tokenStatus, Options options) throws AuthleteApiException { - return getTokenList(clientIdentifier, subject, 0, 0, false, tokenStatus); + return getTokenList(clientIdentifier, subject, 0, 0, false, tokenStatus, options); } @Override - public TokenListResponse getTokenList(int start, int end) throws AuthleteApiException + public TokenListResponse getTokenList(int start, int end, Options options) throws AuthleteApiException { - return getTokenList(null, null, start, end, true, TokenStatus.ALL); + return getTokenList(null, null, start, end, true, TokenStatus.ALL, options); } @Override - public TokenListResponse getTokenList(int start, int end, TokenStatus tokenStatus) throws AuthleteApiException + public TokenListResponse getTokenList(int start, int end, TokenStatus tokenStatus, Options options) throws AuthleteApiException { - return getTokenList(null, null, start, end, true, tokenStatus); + return getTokenList(null, null, start, end, true, tokenStatus, options); } @Override - public TokenListResponse getTokenList(String clientIdentifier, String subject, int start, int end) throws AuthleteApiException + public TokenListResponse getTokenList(String clientIdentifier, String subject, int start, int end, Options options) throws AuthleteApiException { - return getTokenList(clientIdentifier, subject, start, end, true, TokenStatus.ALL); + return getTokenList(clientIdentifier, subject, start, end, true, TokenStatus.ALL, options); } @Override - public TokenListResponse getTokenList(String clientIdentifier, String subject, int start, int end, TokenStatus tokenStatus) throws AuthleteApiException + public TokenListResponse getTokenList(String clientIdentifier, String subject, int start, int end, TokenStatus tokenStatus, Options options) throws AuthleteApiException { - return getTokenList(clientIdentifier, subject, start, end, true, tokenStatus); + return getTokenList(clientIdentifier, subject, start, end, true, tokenStatus, options); } private TokenListResponse getTokenList( final String clientIdentifier, final String subject, - final int start, final int end, final boolean rangeGiven, TokenStatus tokenStatus) throws AuthleteApiException + final int start, final int end, final boolean rangeGiven, TokenStatus tokenStatus, Options options) throws AuthleteApiException { return executeApiCall(new AuthleteApiCall() { @Override public TokenListResponse call() { - return callGetTokenList(clientIdentifier, subject, start, end, rangeGiven, tokenStatus); + return callGetTokenList(clientIdentifier, subject, start, end, rangeGiven, tokenStatus, options); } }); } private TokenListResponse callGetTokenList( - String clientIdentifier, String subject, int start, int end, boolean rangeGiven, TokenStatus tokenStatus) + String clientIdentifier, String subject, int start, int end, boolean rangeGiven, TokenStatus tokenStatus, Options options) { WebTarget target = getTarget().path(AUTH_TOKEN_GET_LIST_API_PATH); @@ -615,10 +636,13 @@ private TokenListResponse callGetTokenList( target = target.queryParam("tokenStatus", tokenStatus.toString()); - return wrapWithDpop(target + Builder builder = wrapWithDpop(target .request(APPLICATION_JSON_TYPE), AUTH_TOKEN_GET_LIST_API_PATH, "GET") - .header(AUTHORIZATION, mServiceAuth) - .get(TokenListResponse.class); + .header(AUTHORIZATION, mServiceAuth); + + setCustomRequestHeaders(builder, options); + + return builder.get(TokenListResponse.class); } @@ -626,11 +650,12 @@ private TokenListResponse callGetTokenList( * Call {@code /api/auth/revocation} API. */ @Override - public RevocationResponse revocation(RevocationRequest request) throws AuthleteApiException + public RevocationResponse revocation(RevocationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - RevocationResponse.class, request, AUTH_REVOCATION_API_PATH)); + RevocationResponse.class, request, AUTH_REVOCATION_API_PATH) + .setOptions(options)); } @@ -638,11 +663,12 @@ public RevocationResponse revocation(RevocationRequest request) throws AuthleteA * Call {@code /api/auth/userinfo} API. */ @Override - public UserInfoResponse userinfo(UserInfoRequest request) throws AuthleteApiException + public UserInfoResponse userinfo(UserInfoRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - UserInfoResponse.class, request, AUTH_USERINFO_API_PATH)); + UserInfoResponse.class, request, AUTH_USERINFO_API_PATH) + .setOptions(options)); } @@ -650,11 +676,12 @@ public UserInfoResponse userinfo(UserInfoRequest request) throws AuthleteApiExce * Call {@code /api/auth/userinfo/issue} API. */ @Override - public UserInfoIssueResponse userinfoIssue(UserInfoIssueRequest request) throws AuthleteApiException + public UserInfoIssueResponse userinfoIssue(UserInfoIssueRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - UserInfoIssueResponse.class, request, AUTH_USERINFO_ISSUE_API_PATH)); + UserInfoIssueResponse.class, request, AUTH_USERINFO_ISSUE_API_PATH) + .setOptions(options)); } @@ -662,11 +689,12 @@ public UserInfoIssueResponse userinfoIssue(UserInfoIssueRequest request) throws * Call {@code /api/auth/introspection} API. */ @Override - public IntrospectionResponse introspection(IntrospectionRequest request) throws AuthleteApiException + public IntrospectionResponse introspection(IntrospectionRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - IntrospectionResponse.class, request, AUTH_INTROSPECTION_API_PATH)); + IntrospectionResponse.class, request, AUTH_INTROSPECTION_API_PATH) + .setOptions(options)); } @@ -675,11 +703,12 @@ public IntrospectionResponse introspection(IntrospectionRequest request) throws */ @Override public StandardIntrospectionResponse standardIntrospection( - StandardIntrospectionRequest request) throws AuthleteApiException + StandardIntrospectionRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - StandardIntrospectionResponse.class, request, AUTH_INTROSPECTION_STANDARD_API_PATH)); + StandardIntrospectionResponse.class, request, AUTH_INTROSPECTION_STANDARD_API_PATH) + .setOptions(options)); } @@ -687,11 +716,12 @@ public StandardIntrospectionResponse standardIntrospection( * Call {@code /api/service/create} API. */ @Override - public Service createService(Service service) throws AuthleteApiException + public Service createService(Service service, Options options) throws AuthleteApiException { return executeApiCall( new ServiceOwnerPostApiCaller( - Service.class, service, SERVICE_CREATE_API_PATH)); + Service.class, service, SERVICE_CREATE_API_PATH) + .setOptions(options)); } @@ -710,11 +740,12 @@ public Service createServie(Service service) throws AuthleteApiException * Call /api/service/delete/{serviceApiKey} API. */ @Override - public void deleteService(long apiKey) throws AuthleteApiException + public void deleteService(long apiKey, Options options) throws AuthleteApiException { executeApiCall( new ServiceOwnerDeleteApiCaller( - SERVICE_DELETE_API_PATH, apiKey)); + SERVICE_DELETE_API_PATH, apiKey) + .setOptions(options)); } @@ -722,11 +753,12 @@ public void deleteService(long apiKey) throws AuthleteApiException * Call /api/service/get/{serviceApiKey} API. */ @Override - public Service getService(long apiKey) throws AuthleteApiException + public Service getService(long apiKey, Options options) throws AuthleteApiException { return executeApiCall( new ServiceOwnerGetApiCaller( - Service.class, SERVICE_GET_API_PATH, apiKey)); + Service.class, SERVICE_GET_API_PATH, apiKey) + .setOptions(options)); } @@ -734,28 +766,28 @@ public Service getService(long apiKey) throws AuthleteApiException * Call {@code /api/service/get/list} API. */ @Override - public ServiceListResponse getServiceList() throws AuthleteApiException + public ServiceListResponse getServiceList(Options options) throws AuthleteApiException { - return getServiceList(0, 0, false); + return getServiceList(0, 0, false, options); } @Override - public ServiceListResponse getServiceList(int start, int end) throws AuthleteApiException + public ServiceListResponse getServiceList(int start, int end, Options options) throws AuthleteApiException { - return getServiceList(start, end, true); + return getServiceList(start, end, true, options); } private ServiceListResponse getServiceList( - final int start, final int end, final boolean rangeGiven) throws AuthleteApiException + final int start, final int end, final boolean rangeGiven, Options options) throws AuthleteApiException { return executeApiCall(new AuthleteApiCall() { @Override public ServiceListResponse call() { - return callGetServiceList(start, end, rangeGiven); + return callGetServiceList(start, end, rangeGiven, options); } }); } @@ -764,7 +796,7 @@ public ServiceListResponse call() /** * Call /service/get/list. */ - private ServiceListResponse callGetServiceList(int start, int end, boolean rangeGiven) + private ServiceListResponse callGetServiceList(int start, int end, boolean rangeGiven, Options options) { WebTarget target = getTarget().path(SERVICE_GET_LIST_API_PATH); @@ -773,10 +805,13 @@ private ServiceListResponse callGetServiceList(int start, int end, boolean range target = target.queryParam("start", start).queryParam("end", end); } - return wrapWithDpop(target + Builder builder = wrapWithDpop(target .request(APPLICATION_JSON_TYPE), SERVICE_GET_LIST_API_PATH, "GET") - .header(AUTHORIZATION, mServiceOwnerAuth) - .get(ServiceListResponse.class); + .header(AUTHORIZATION, mServiceOwnerAuth); + + setCustomRequestHeaders(builder, options); + + return builder.get(ServiceListResponse.class); } @@ -784,11 +819,12 @@ private ServiceListResponse callGetServiceList(int start, int end, boolean range * Call /api/service/update/{serviceApiKey} API. */ @Override - public Service updateService(final Service service) throws AuthleteApiException + public Service updateService(final Service service, Options options) throws AuthleteApiException { return executeApiCall( new ServiceOwnerPostApiCaller( - Service.class, service, SERVICE_UPDATE_API_PATH, service.getApiKey())); + Service.class, service, SERVICE_UPDATE_API_PATH, service.getApiKey()) + .setOptions(options)); } @@ -796,11 +832,12 @@ public Service updateService(final Service service) throws AuthleteApiException * Call {@code /api/service/jwks/get} API */ @Override - public String getServiceJwks() throws AuthleteApiException + public String getServiceJwks(Options options) throws AuthleteApiException { return executeApiCall( new ServiceGetApiCaller( - String.class, SERVICE_JWKS_GET_API_PATH)); + String.class, SERVICE_JWKS_GET_API_PATH) + .setOptions(options)); } @@ -808,13 +845,14 @@ public String getServiceJwks() throws AuthleteApiException * Call {@code /api/service/jwks/get} API */ @Override - public String getServiceJwks(boolean pretty, boolean includePrivateKeys) throws AuthleteApiException + public String getServiceJwks(boolean pretty, boolean includePrivateKeys, Options options) throws AuthleteApiException { return executeApiCall( new ServiceGetApiCaller( String.class, SERVICE_JWKS_GET_API_PATH) .addParam("pretty", pretty) - .addParam("includePrivateKeys", includePrivateKeys)); + .addParam("includePrivateKeys", includePrivateKeys) + .setOptions(options)); } @@ -822,11 +860,12 @@ public String getServiceJwks(boolean pretty, boolean includePrivateKeys) throws * Call {@code /api/service/configuration} API */ @Override - public String getServiceConfiguration() throws AuthleteApiException + public String getServiceConfiguration(Options options) throws AuthleteApiException { return executeApiCall( new ServiceGetApiCaller( - String.class, SERVICE_CONFIGURATION_API_PATH)); + String.class, SERVICE_CONFIGURATION_API_PATH) + .setOptions(options)); } @@ -834,12 +873,13 @@ public String getServiceConfiguration() throws AuthleteApiException * Call {@code /api/service/configuration} API */ @Override - public String getServiceConfiguration(boolean pretty) throws AuthleteApiException + public String getServiceConfiguration(boolean pretty, Options options) throws AuthleteApiException { return executeApiCall( new ServiceGetApiCaller( String.class, SERVICE_CONFIGURATION_API_PATH) - .addParam("pretty", pretty)); + .addParam("pretty", pretty) + .setOptions(options)); } @@ -847,11 +887,12 @@ public String getServiceConfiguration(boolean pretty) throws AuthleteApiExceptio * Call {@code /api/service/configuration} API */ @Override - public String getServiceConfiguration(ServiceConfigurationRequest request) throws AuthleteApiException + public String getServiceConfiguration(ServiceConfigurationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - String.class, request, SERVICE_CONFIGURATION_API_PATH)); + String.class, request, SERVICE_CONFIGURATION_API_PATH) + .setOptions(options)); } @@ -859,11 +900,12 @@ public String getServiceConfiguration(ServiceConfigurationRequest request) throw * Call {@code /api/client/create} API. */ @Override - public Client createClient(Client client) throws AuthleteApiException + public Client createClient(Client client, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - Client.class, client, CLIENT_CREATE_API_PATH)); + Client.class, client, CLIENT_CREATE_API_PATH) + .setOptions(options)); } @@ -871,11 +913,12 @@ public Client createClient(Client client) throws AuthleteApiException * Call {@code /api/client/registration} API. */ @Override - public ClientRegistrationResponse dynamicClientRegister(ClientRegistrationRequest request) throws AuthleteApiException + public ClientRegistrationResponse dynamicClientRegister(ClientRegistrationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_API_PATH)); + ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_API_PATH) + .setOptions(options)); } @@ -883,11 +926,12 @@ public ClientRegistrationResponse dynamicClientRegister(ClientRegistrationReques * Call {@code /api/client/registration/get} API. */ @Override - public ClientRegistrationResponse dynamicClientGet(ClientRegistrationRequest request) throws AuthleteApiException + public ClientRegistrationResponse dynamicClientGet(ClientRegistrationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_GET_API_PATH)); + ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_GET_API_PATH) + .setOptions(options)); } @@ -895,11 +939,12 @@ public ClientRegistrationResponse dynamicClientGet(ClientRegistrationRequest req * Call {@code /api/client/registration/update} API. */ @Override - public ClientRegistrationResponse dynamicClientUpdate(ClientRegistrationRequest request) throws AuthleteApiException + public ClientRegistrationResponse dynamicClientUpdate(ClientRegistrationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_UPDATE_API_PATH)); + ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_UPDATE_API_PATH) + .setOptions(options)); } @@ -907,11 +952,12 @@ public ClientRegistrationResponse dynamicClientUpdate(ClientRegistrationRequest * Call {@code /api/client/registration/delete} API. */ @Override - public ClientRegistrationResponse dynamicClientDelete(ClientRegistrationRequest request) throws AuthleteApiException + public ClientRegistrationResponse dynamicClientDelete(ClientRegistrationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_DELETE_API_PATH)); + ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_DELETE_API_PATH) + .setOptions(options)); } @@ -919,9 +965,9 @@ public ClientRegistrationResponse dynamicClientDelete(ClientRegistrationRequest * Call /api/client/delete/{clientId} API. */ @Override - public void deleteClient(long clientId) throws AuthleteApiException + public void deleteClient(long clientId, Options options) throws AuthleteApiException { - deleteClient(String.valueOf(clientId)); + deleteClient(String.valueOf(clientId), options); } @@ -929,11 +975,12 @@ public void deleteClient(long clientId) throws AuthleteApiException * Call /api/client/delete/{clientId} API. */ @Override - public void deleteClient(String clientId) throws AuthleteApiException + public void deleteClient(String clientId, Options options) throws AuthleteApiException { executeApiCall( new ServiceDeleteApiCaller( - CLIENT_DELETE_API_PATH, clientId)); + CLIENT_DELETE_API_PATH, clientId) + .setOptions(options)); } @@ -941,9 +988,9 @@ public void deleteClient(String clientId) throws AuthleteApiException * Call /api/client/get/{clientId} API. */ @Override - public Client getClient(long clientId) throws AuthleteApiException + public Client getClient(long clientId, Options options) throws AuthleteApiException { - return getClient(String.valueOf(clientId)); + return getClient(String.valueOf(clientId), options); } @@ -951,11 +998,12 @@ public Client getClient(long clientId) throws AuthleteApiException * Call /api/client/get/{clientId} API. */ @Override - public Client getClient(String clientId) throws AuthleteApiException + public Client getClient(String clientId, Options options) throws AuthleteApiException { return executeApiCall( new ServiceGetApiCaller( - Client.class, CLIENT_GET_API_PATH, clientId)); + Client.class, CLIENT_GET_API_PATH, clientId) + .setOptions(options)); } @@ -963,48 +1011,48 @@ public Client getClient(String clientId) throws AuthleteApiException * Call {@code /api/client/get/list} API. */ @Override - public ClientListResponse getClientList() throws AuthleteApiException + public ClientListResponse getClientList(Options options) throws AuthleteApiException { - return getClientList(null, 0, 0, false); + return getClientList(null, 0, 0, false, options); } @Override - public ClientListResponse getClientList(String developer) throws AuthleteApiException + public ClientListResponse getClientList(String developer, Options options) throws AuthleteApiException { - return getClientList(developer, 0, 0, false); + return getClientList(developer, 0, 0, false, options); } @Override - public ClientListResponse getClientList(int start, int end) throws AuthleteApiException + public ClientListResponse getClientList(int start, int end, Options options) throws AuthleteApiException { - return getClientList(null, start, end, true); + return getClientList(null, start, end, true, options); } @Override - public ClientListResponse getClientList(String developer, int start, int end) throws AuthleteApiException + public ClientListResponse getClientList(String developer, int start, int end, Options options) throws AuthleteApiException { - return getClientList(developer, start, end, true); + return getClientList(developer, start, end, true, options); } private ClientListResponse getClientList( - final String developer, final int start, final int end, final boolean rangeGiven) throws AuthleteApiException + final String developer, final int start, final int end, final boolean rangeGiven, Options options) throws AuthleteApiException { return executeApiCall(new AuthleteApiCall() { @Override public ClientListResponse call() { - return callGetClientList(developer, start, end, rangeGiven); + return callGetClientList(developer, start, end, rangeGiven, options); } }); } - private ClientListResponse callGetClientList(String developer, int start, int end, boolean rangeGiven) + private ClientListResponse callGetClientList(String developer, int start, int end, boolean rangeGiven, Options options) { WebTarget target = getTarget().path(CLIENT_GET_LIST_API_PATH); @@ -1018,10 +1066,13 @@ private ClientListResponse callGetClientList(String developer, int start, int en target = target.queryParam("start", start).queryParam("end", end); } - return wrapWithDpop(target + Builder builder = wrapWithDpop(target .request(APPLICATION_JSON_TYPE), CLIENT_GET_LIST_API_PATH, "GET") - .header(AUTHORIZATION, mServiceAuth) - .get(ClientListResponse.class); + .header(AUTHORIZATION, mServiceAuth); + + setCustomRequestHeaders(builder, options); + + return builder.get(ClientListResponse.class); } @@ -1029,11 +1080,12 @@ private ClientListResponse callGetClientList(String developer, int start, int en * Call /api/client/update/{clientId} API. */ @Override - public Client updateClient(Client client) throws AuthleteApiException + public Client updateClient(Client client, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - Client.class, client, CLIENT_UPDATE_API_PATH, client.getClientId())); + Client.class, client, CLIENT_UPDATE_API_PATH, client.getClientId()) + .setOptions(options)); } @@ -1042,12 +1094,13 @@ public Client updateClient(Client client) throws AuthleteApiException * Call /api/client/extension/requestable_scopes/get/{clientId} API. */ @Override - public String[] getRequestableScopes(long clientId) throws AuthleteApiException + public String[] getRequestableScopes(long clientId, Options options) throws AuthleteApiException { // Call the API. RequestableScopes response = executeApiCall( new ServiceGetApiCaller( - RequestableScopes.class, REQUESTABLE_SCOPES_GET_API_PATH, clientId)); + RequestableScopes.class, REQUESTABLE_SCOPES_GET_API_PATH, clientId) + .setOptions(options)); if (response != null) { @@ -1062,7 +1115,7 @@ public String[] getRequestableScopes(long clientId) throws AuthleteApiException @Override - public String[] setRequestableScopes(long clientId, String[] scopes) throws AuthleteApiException + public String[] setRequestableScopes(long clientId, String[] scopes, Options options) throws AuthleteApiException { // Prepare a request body. RequestableScopes request = new RequestableScopes().setRequestableScopes(scopes); @@ -1088,16 +1141,17 @@ public String[] setRequestableScopes(long clientId, String[] scopes) throws Auth * Call /api/client/extension/requestable_scopes/delete/{clientId} API. */ @Override - public void deleteRequestableScopes(long clientId) throws AuthleteApiException + public void deleteRequestableScopes(long clientId, Options options) throws AuthleteApiException { executeApiCall( new ServiceDeleteApiCaller( - REQUESTABLE_SCOPES_DELETE_API_PATH, clientId)); + REQUESTABLE_SCOPES_DELETE_API_PATH, clientId) + .setOptions(options)); } @Override - public GrantedScopesGetResponse getGrantedScopes(long clientId, String subject) + public GrantedScopesGetResponse getGrantedScopes(long clientId, String subject, Options options) { // Prepare a request body. GrantedScopesRequest request = new GrantedScopesRequest(subject); @@ -1105,19 +1159,21 @@ public GrantedScopesGetResponse getGrantedScopes(long clientId, String subject) // Call the API. return executeApiCall( new ServicePostApiCaller( - GrantedScopesGetResponse.class, request, GRANTED_SCOPES_GET_API_PATH, clientId)); + GrantedScopesGetResponse.class, request, GRANTED_SCOPES_GET_API_PATH, clientId) + .setOptions(options)); } @Override - public void deleteGrantedScopes(long clientId, String subject) + public void deleteGrantedScopes(long clientId, String subject, Options options) { // Prepare a request body. GrantedScopesRequest request = new GrantedScopesRequest(subject); executeApiCall( new ServicePostApiCaller( - ApiResponse.class, request, GRANTED_SCOPES_DELETE_API_PATH, clientId)); + ApiResponse.class, request, GRANTED_SCOPES_DELETE_API_PATH, clientId) + .setOptions(options)); } @@ -1148,61 +1204,69 @@ public void setSubject(String subject) @Override - public void deleteClientAuthorization(long clientId, String subject) throws AuthleteApiException + public void deleteClientAuthorization(long clientId, String subject, Options options) throws AuthleteApiException { // Prepare a request body. ClientAuthorizationDeleteRequest request = new ClientAuthorizationDeleteRequest(subject); executeApiCall( new ServicePostApiCaller( - ApiResponse.class, request, CLIENT_AUTHORIZATION_DELETE_API_PATH, clientId)); + ApiResponse.class, request, CLIENT_AUTHORIZATION_DELETE_API_PATH, clientId) + .setOptions(options)); } @Override - public AuthorizedClientListResponse getClientAuthorizationList(ClientAuthorizationGetListRequest request) throws AuthleteApiException + public AuthorizedClientListResponse getClientAuthorizationList( + ClientAuthorizationGetListRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - AuthorizedClientListResponse.class, request, CLIENT_AUTHORIZATION_GET_LIST_API_PATH)); + AuthorizedClientListResponse.class, request, CLIENT_AUTHORIZATION_GET_LIST_API_PATH) + .setOptions(options)); } @Override - public void updateClientAuthorization(long clientId, ClientAuthorizationUpdateRequest request) throws AuthleteApiException + public void updateClientAuthorization( + long clientId, ClientAuthorizationUpdateRequest request, Options options) throws AuthleteApiException { executeApiCall( new ServicePostApiCaller( - ApiResponse.class, request, CLIENT_AUTHORIZATION_UPDATE_API_PATH, clientId)); + ApiResponse.class, request, CLIENT_AUTHORIZATION_UPDATE_API_PATH, clientId) + .setOptions(options)); } @Override - public ClientSecretRefreshResponse refreshClientSecret(long clientId) throws AuthleteApiException + public ClientSecretRefreshResponse refreshClientSecret(long clientId, Options options) throws AuthleteApiException { - return refreshClientSecret(String.valueOf(clientId)); + return refreshClientSecret(String.valueOf(clientId), options); } @Override - public ClientSecretRefreshResponse refreshClientSecret(String clientIdentifier) throws AuthleteApiException + public ClientSecretRefreshResponse refreshClientSecret(String clientIdentifier, Options options) throws AuthleteApiException { return executeApiCall( new ServiceGetApiCaller( ClientSecretRefreshResponse.class, - CLIENT_SECRET_REFRESH_API_PATH, clientIdentifier)); + CLIENT_SECRET_REFRESH_API_PATH, clientIdentifier) + .setOptions(options)); } @Override - public ClientSecretUpdateResponse updateClientSecret(long clientId, String clientSecret) throws AuthleteApiException + public ClientSecretUpdateResponse updateClientSecret( + long clientId, String clientSecret, Options options) throws AuthleteApiException { - return updateClientSecret(String.valueOf(clientId), clientSecret); + return updateClientSecret(String.valueOf(clientId), clientSecret, options); } @Override - public ClientSecretUpdateResponse updateClientSecret(String clientIdentifier, String clientSecret) throws AuthleteApiException + public ClientSecretUpdateResponse updateClientSecret( + String clientIdentifier, String clientSecret, Options options) throws AuthleteApiException { // Prepare a request body. setClientSecret(String) method // throws IllegalArgumentException if the given client secret @@ -1213,7 +1277,8 @@ public ClientSecretUpdateResponse updateClientSecret(String clientIdentifier, St return executeApiCall( new ServicePostApiCaller( ClientSecretUpdateResponse.class, request, - CLIENT_SECRET_UPDATE_API_PATH, clientIdentifier)); + CLIENT_SECRET_UPDATE_API_PATH, clientIdentifier) + .setOptions(options)); } @@ -1221,11 +1286,12 @@ public ClientSecretUpdateResponse updateClientSecret(String clientIdentifier, St * Call {@code /api/jose/verify} API. */ @Override - public JoseVerifyResponse verifyJose(JoseVerifyRequest request) throws AuthleteApiException + public JoseVerifyResponse verifyJose(JoseVerifyRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - JoseVerifyResponse.class, request, JOSE_VERIFY_API_PATH)); + JoseVerifyResponse.class, request, JOSE_VERIFY_API_PATH) + .setOptions(options)); } @@ -1233,11 +1299,13 @@ public JoseVerifyResponse verifyJose(JoseVerifyRequest request) throws AuthleteA * Call {@code /api/backchannel/authentication} API. */ @Override - public BackchannelAuthenticationResponse backchannelAuthentication(BackchannelAuthenticationRequest request) throws AuthleteApiException + public BackchannelAuthenticationResponse backchannelAuthentication( + BackchannelAuthenticationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - BackchannelAuthenticationResponse.class, request, BACKCHANNEL_AUTHENTICATION_API_PATH)); + BackchannelAuthenticationResponse.class, request, BACKCHANNEL_AUTHENTICATION_API_PATH) + .setOptions(options)); } @@ -1245,11 +1313,13 @@ public BackchannelAuthenticationResponse backchannelAuthentication(BackchannelAu * Call {@code /api/backchannel/authentication/issue} API. */ @Override - public BackchannelAuthenticationIssueResponse backchannelAuthenticationIssue(BackchannelAuthenticationIssueRequest request) throws AuthleteApiException + public BackchannelAuthenticationIssueResponse backchannelAuthenticationIssue( + BackchannelAuthenticationIssueRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - BackchannelAuthenticationIssueResponse.class, request, BACKCHANNEL_AUTHENTICATION_ISSUE_API_PATH)); + BackchannelAuthenticationIssueResponse.class, request, BACKCHANNEL_AUTHENTICATION_ISSUE_API_PATH) + .setOptions(options)); } @@ -1257,11 +1327,13 @@ public BackchannelAuthenticationIssueResponse backchannelAuthenticationIssue(Bac * Call {@code /api/backchannel/authentication/fail} API. */ @Override - public BackchannelAuthenticationFailResponse backchannelAuthenticationFail(BackchannelAuthenticationFailRequest request) throws AuthleteApiException + public BackchannelAuthenticationFailResponse backchannelAuthenticationFail( + BackchannelAuthenticationFailRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - BackchannelAuthenticationFailResponse.class, request, BACKCHANNEL_AUTHENTICATION_FAIL_API_PATH)); + BackchannelAuthenticationFailResponse.class, request, BACKCHANNEL_AUTHENTICATION_FAIL_API_PATH) + .setOptions(options)); } @@ -1269,11 +1341,13 @@ public BackchannelAuthenticationFailResponse backchannelAuthenticationFail(Backc * Call {@code /api/backchannel/authentication/complete} API. */ @Override - public BackchannelAuthenticationCompleteResponse backchannelAuthenticationComplete(BackchannelAuthenticationCompleteRequest request) throws AuthleteApiException + public BackchannelAuthenticationCompleteResponse backchannelAuthenticationComplete( + BackchannelAuthenticationCompleteRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - BackchannelAuthenticationCompleteResponse.class, request, BACKCHANNEL_AUTHENTICATION_COMPLETE_API_PATH)); + BackchannelAuthenticationCompleteResponse.class, request, BACKCHANNEL_AUTHENTICATION_COMPLETE_API_PATH) + .setOptions(options)); } @@ -1281,11 +1355,13 @@ public BackchannelAuthenticationCompleteResponse backchannelAuthenticationComple * Call {@code /api/device/authorization} API. */ @Override - public DeviceAuthorizationResponse deviceAuthorization(DeviceAuthorizationRequest request) throws AuthleteApiException + public DeviceAuthorizationResponse deviceAuthorization( + DeviceAuthorizationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - DeviceAuthorizationResponse.class, request, DEVICE_AUTHORIZATION_API_PATH)); + DeviceAuthorizationResponse.class, request, DEVICE_AUTHORIZATION_API_PATH) + .setOptions(options)); } @@ -1293,11 +1369,13 @@ public DeviceAuthorizationResponse deviceAuthorization(DeviceAuthorizationReques * Call {@code /api/device/complete} API. */ @Override - public DeviceCompleteResponse deviceComplete(DeviceCompleteRequest request) throws AuthleteApiException + public DeviceCompleteResponse deviceComplete( + DeviceCompleteRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - DeviceCompleteResponse.class, request, DEVICE_COMPLETE_API_PATH)); + DeviceCompleteResponse.class, request, DEVICE_COMPLETE_API_PATH) + .setOptions(options)); } @@ -1305,77 +1383,85 @@ public DeviceCompleteResponse deviceComplete(DeviceCompleteRequest request) thro * Call {@code /api/device/verification} API. */ @Override - public DeviceVerificationResponse deviceVerification(DeviceVerificationRequest request) throws AuthleteApiException + public DeviceVerificationResponse deviceVerification( + DeviceVerificationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - DeviceVerificationResponse.class, request, DEVICE_VERIFICATION_API_PATH)); + DeviceVerificationResponse.class, request, DEVICE_VERIFICATION_API_PATH) + .setOptions(options)); } @Override - public PushedAuthReqResponse pushAuthorizationRequest(PushedAuthReqRequest request) throws AuthleteApiException + public PushedAuthReqResponse pushAuthorizationRequest( + PushedAuthReqRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - PushedAuthReqResponse.class, request, PUSHED_AUTH_REQ_API_PATH)); + PushedAuthReqResponse.class, request, PUSHED_AUTH_REQ_API_PATH) + .setOptions(options)); } @Override - public HskResponse hskCreate(HskCreateRequest request) throws AuthleteApiException + public HskResponse hskCreate(HskCreateRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - HskResponse.class, request, HSK_CREATE_API_PATH)); + HskResponse.class, request, HSK_CREATE_API_PATH) + .setOptions(options)); } @Override - public HskResponse hskDelete(String handle) throws AuthleteApiException + public HskResponse hskDelete(String handle, Options options) throws AuthleteApiException { return executeApiCall( new ServiceGetApiCaller( HskResponse.class, - HSK_DELETE_API_PATH, handle)); + HSK_DELETE_API_PATH, handle) + .setOptions(options)); } @Override - public HskResponse hskGet(String handle) throws AuthleteApiException + public HskResponse hskGet(String handle, Options options) throws AuthleteApiException { return executeApiCall( new ServiceGetApiCaller( HskResponse.class, - HSK_GET_API_PATH, handle)); + HSK_GET_API_PATH, handle) + .setOptions(options)); } @Override - public HskListResponse hskGetList() throws AuthleteApiException + public HskListResponse hskGetList(Options options) throws AuthleteApiException { return executeApiCall( new ServiceGetApiCaller( HskListResponse.class, - HSK_GET_LIST_API_PATH)); + HSK_GET_LIST_API_PATH) + .setOptions(options)); } @Override - public Map echo(Map parameters) throws AuthleteApiException + public Map echo(Map parameters, Options options) throws AuthleteApiException { return executeApiCall(new AuthleteApiCall>() { @Override public Map call() { - return callEcho(parameters); + return callEcho(parameters, options); } }); } - private Map callEcho(Map parameters) + private Map callEcho(Map parameters, Options options) { WebTarget target = getTarget().path(ECHO_API_PATH); @@ -1390,24 +1476,27 @@ private Map callEcho(Map parameters) // The API does not require any authentication, so the code below // does not include '.header(AUTHORIZATION, ...)'. - return target - .request(APPLICATION_JSON_TYPE) - .get(new GenericType>(){}); + Builder builder = target.request(APPLICATION_JSON_TYPE); + + setCustomRequestHeaders(builder, options); + + return builder.get(new GenericType>(){}); } @Override - public GMResponse gm(GMRequest request) throws AuthleteApiException + public GMResponse gm(GMRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( - GMResponse.class, request, GM_API_PATH)); + GMResponse.class, request, GM_API_PATH) + .setOptions(options)); } @Override public void updateClientLockFlag( - String clientIdentifier, boolean clientLocked) throws AuthleteApiException + String clientIdentifier, boolean clientLocked, Options options) throws AuthleteApiException { // Prepare a request body. ClientLockFlagUpdateRequest request = @@ -1416,35 +1505,38 @@ public void updateClientLockFlag( executeApiCall( new ServicePostApiCaller( ApiResponse.class, request, - CLIENT_LOCK_FLAG_UPDATE_API_PATH, clientIdentifier)); + CLIENT_LOCK_FLAG_UPDATE_API_PATH, clientIdentifier) + .setOptions(options)); } @Override public FederationConfigurationResponse federationConfiguration( - FederationConfigurationRequest request) throws AuthleteApiException + FederationConfigurationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( FederationConfigurationResponse.class, request, - FEDERATION_CONFIGURATION_API_PATH)); + FEDERATION_CONFIGURATION_API_PATH) + .setOptions(options)); } @Override public FederationRegistrationResponse federationRegistration( - FederationRegistrationRequest request) throws AuthleteApiException + FederationRegistrationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( FederationRegistrationResponse.class, request, - FEDERATION_REGISTRATION_API_PATH)); + FEDERATION_REGISTRATION_API_PATH) + .setOptions(options)); } @Override public CredentialIssuerMetadataResponse credentialIssuerMetadata( - CredentialIssuerMetadataRequest request) throws AuthleteApiException + CredentialIssuerMetadataRequest request, Options options) throws AuthleteApiException { // Note that the /vci/metadata API is not available in Authlete 2.x, // so the executeApiCall below will throw an exception. @@ -1452,13 +1544,14 @@ public CredentialIssuerMetadataResponse credentialIssuerMetadata( return executeApiCall( new ServicePostApiCaller( CredentialIssuerMetadataResponse.class, request, - VCI_METADATA_API_PATH)); + VCI_METADATA_API_PATH) + .setOptions(options)); } @Override public CredentialJwtIssuerMetadataResponse credentialJwtIssuerMetadata( - CredentialJwtIssuerMetadataRequest request) throws AuthleteApiException + CredentialJwtIssuerMetadataRequest request, Options options) throws AuthleteApiException { // Note that the /vci/jwtissuer API is not available in Authlete 2.x, // so the executeApiCall below will throw an exception. @@ -1466,13 +1559,14 @@ public CredentialJwtIssuerMetadataResponse credentialJwtIssuerMetadata( return executeApiCall( new ServicePostApiCaller( CredentialJwtIssuerMetadataResponse.class, request, - VCI_JWT_ISSUER_API_PATH)); + VCI_JWT_ISSUER_API_PATH) + .setOptions(options)); } @Override public CredentialIssuerJwksResponse credentialIssuerJwks( - CredentialIssuerJwksRequest request) throws AuthleteApiException + CredentialIssuerJwksRequest request, Options options) throws AuthleteApiException { // Note that the /vci/jwks API is not available in Authlete 2.x, // so the executeApiCall below will throw an exception. @@ -1480,13 +1574,14 @@ public CredentialIssuerJwksResponse credentialIssuerJwks( return executeApiCall( new ServicePostApiCaller( CredentialIssuerJwksResponse.class, request, - VCI_JWKS_API_PATH)); + VCI_JWKS_API_PATH) + .setOptions(options)); } @Override public CredentialOfferCreateResponse credentialOfferCreate( - CredentialOfferCreateRequest request) throws AuthleteApiException + CredentialOfferCreateRequest request, Options options) throws AuthleteApiException { // Note that the /vci/offer/create API is not available in Authlete 2.x, // so the executeApiCall below will throw an exception. @@ -1494,13 +1589,14 @@ public CredentialOfferCreateResponse credentialOfferCreate( return executeApiCall( new ServicePostApiCaller( CredentialOfferCreateResponse.class, request, - VCI_OFFER_CREATE_API_PATH)); + VCI_OFFER_CREATE_API_PATH) + .setOptions(options)); } @Override public CredentialOfferInfoResponse credentialOfferInfo( - CredentialOfferInfoRequest request) throws AuthleteApiException + CredentialOfferInfoRequest request, Options options) throws AuthleteApiException { // Note that the /vci/offer/info API is not available in Authlete 2.x, // so the executeApiCall below will throw an exception. @@ -1508,13 +1604,14 @@ public CredentialOfferInfoResponse credentialOfferInfo( return executeApiCall( new ServicePostApiCaller( CredentialOfferInfoResponse.class, request, - VCI_OFFER_INFO_API_PATH)); + VCI_OFFER_INFO_API_PATH) + .setOptions(options)); } @Override public CredentialSingleParseResponse credentialSingleParse( - CredentialSingleParseRequest request) throws AuthleteApiException + CredentialSingleParseRequest request, Options options) throws AuthleteApiException { // Note that the /vci/single/parse API is not available in Authlete 2.x, // so the executeApiCall below will throw an exception. @@ -1522,13 +1619,14 @@ public CredentialSingleParseResponse credentialSingleParse( return executeApiCall( new ServicePostApiCaller( CredentialSingleParseResponse.class, request, - VCI_SINGLE_PARSE_API_PATH)); + VCI_SINGLE_PARSE_API_PATH) + .setOptions(options)); } @Override public CredentialSingleIssueResponse credentialSingleIssue( - CredentialSingleIssueRequest request) throws AuthleteApiException + CredentialSingleIssueRequest request, Options options) throws AuthleteApiException { // Note that the /vci/single/issue API is not available in Authlete 2.x, // so the executeApiCall below will throw an exception. @@ -1536,13 +1634,14 @@ public CredentialSingleIssueResponse credentialSingleIssue( return executeApiCall( new ServicePostApiCaller( CredentialSingleIssueResponse.class, request, - VCI_SINGLE_ISSUE_API_PATH)); + VCI_SINGLE_ISSUE_API_PATH) + .setOptions(options)); } @Override public CredentialBatchParseResponse credentialBatchParse( - CredentialBatchParseRequest request) throws AuthleteApiException + CredentialBatchParseRequest request, Options options) throws AuthleteApiException { // Note that the /vci/batch/parse API is not available in Authlete 2.x, // so the executeApiCall below will throw an exception. @@ -1550,13 +1649,14 @@ public CredentialBatchParseResponse credentialBatchParse( return executeApiCall( new ServicePostApiCaller( CredentialBatchParseResponse.class, request, - VCI_BATCH_PARSE_API_PATH)); + VCI_BATCH_PARSE_API_PATH) + .setOptions(options)); } @Override public CredentialBatchIssueResponse credentialBatchIssue( - CredentialBatchIssueRequest request) throws AuthleteApiException + CredentialBatchIssueRequest request, Options options) throws AuthleteApiException { // Note that the /vci/batch/issue API is not available in Authlete 2.x, // so the executeApiCall below will throw an exception. @@ -1564,13 +1664,14 @@ public CredentialBatchIssueResponse credentialBatchIssue( return executeApiCall( new ServicePostApiCaller( CredentialBatchIssueResponse.class, request, - VCI_BATCH_ISSUE_API_PATH)); + VCI_BATCH_ISSUE_API_PATH) + .setOptions(options)); } @Override public CredentialDeferredParseResponse credentialDeferredParse( - CredentialDeferredParseRequest request) throws AuthleteApiException + CredentialDeferredParseRequest request, Options options) throws AuthleteApiException { // Note that the /vci/deferred/parse API is not available in Authlete 2.x, // so the executeApiCall below will throw an exception. @@ -1578,13 +1679,14 @@ public CredentialDeferredParseResponse credentialDeferredParse( return executeApiCall( new ServicePostApiCaller( CredentialDeferredParseResponse.class, request, - VCI_DEFERRED_PARSE_API_PATH)); + VCI_DEFERRED_PARSE_API_PATH) + .setOptions(options)); } @Override public CredentialDeferredIssueResponse credentialDeferredIssue( - CredentialDeferredIssueRequest request) throws AuthleteApiException + CredentialDeferredIssueRequest request, Options options) throws AuthleteApiException { // Note that the /vci/deferred/issue API is not available in Authlete 2.x, // so the executeApiCall below will throw an exception. @@ -1592,24 +1694,26 @@ public CredentialDeferredIssueResponse credentialDeferredIssue( return executeApiCall( new ServicePostApiCaller( CredentialDeferredIssueResponse.class, request, - VCI_DEFERRED_ISSUE_API_PATH)); + VCI_DEFERRED_ISSUE_API_PATH) + .setOptions(options)); } @Override public IDTokenReissueResponse idTokenReissue( - IDTokenReissueRequest request) throws AuthleteApiException + IDTokenReissueRequest request, Options options) throws AuthleteApiException { return executeApiCall( new ServicePostApiCaller( IDTokenReissueResponse.class, request, - ID_TOKEN_REISSUE_API_PATH)); + ID_TOKEN_REISSUE_API_PATH) + .setOptions(options)); } @Override public AuthorizationTicketInfoResponse authorizationTicketInfo( - AuthorizationTicketInfoRequest request) throws AuthleteApiException + AuthorizationTicketInfoRequest request, Options options) throws AuthleteApiException { // Note that the /auth/authorization/ticket/info API is not available // in Authlete 2.x, so the executeApiCall below will throw an exception. @@ -1617,13 +1721,14 @@ public AuthorizationTicketInfoResponse authorizationTicketInfo( return executeApiCall( new ServicePostApiCaller( AuthorizationTicketInfoResponse.class, request, - AUTH_AUTHORIZATION_TICKET_INFO_API_PATH)); + AUTH_AUTHORIZATION_TICKET_INFO_API_PATH) + .setOptions(options)); } @Override public AuthorizationTicketUpdateResponse authorizationTicketUpdate( - AuthorizationTicketUpdateRequest request) throws AuthleteApiException + AuthorizationTicketUpdateRequest request, Options options) throws AuthleteApiException { // Note that the /auth/authorization/ticket/update API is not available // in Authlete 2.x, so the executeApiCall below will throw an exception. @@ -1631,13 +1736,14 @@ public AuthorizationTicketUpdateResponse authorizationTicketUpdate( return executeApiCall( new ServicePostApiCaller( AuthorizationTicketUpdateResponse.class, request, - AUTH_AUTHORIZATION_TICKET_UPDATE_API_PATH)); + AUTH_AUTHORIZATION_TICKET_UPDATE_API_PATH) + .setOptions(options)); } @Override public TokenCreateBatchResponse tokenCreateBatch( - TokenCreateRequest[] tokenCreateRequests, boolean dryRun) throws AuthleteApiException + TokenCreateRequest[] tokenCreateRequests, boolean dryRun, Options options) throws AuthleteApiException { throw new AuthleteApiException( "This method can't be invoked since the corresponding API is not supported."); @@ -1646,7 +1752,7 @@ public TokenCreateBatchResponse tokenCreateBatch( @Override public TokenCreateBatchStatusResponse getTokenCreateBatchStatus( - String requestId) throws AuthleteApiException + String requestId, Options options) throws AuthleteApiException { throw new AuthleteApiException( "This method can't be invoked since the corresponding API is not supported."); diff --git a/src/main/java/com/authlete/jakarta/api/AuthleteApiImplV3.java b/src/main/java/com/authlete/jakarta/api/AuthleteApiImplV3.java index 0972cce..8b52a93 100644 --- a/src/main/java/com/authlete/jakarta/api/AuthleteApiImplV3.java +++ b/src/main/java/com/authlete/jakarta/api/AuthleteApiImplV3.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2023 Authlete, Inc. + * Copyright (C) 2014-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,10 +21,12 @@ import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import java.util.LinkedHashMap; import java.util.Map; +import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.client.WebTarget; import jakarta.ws.rs.core.GenericType; import com.authlete.common.api.AuthleteApi; import com.authlete.common.api.AuthleteApiException; +import com.authlete.common.api.Options; import com.authlete.common.conf.AuthleteApiVersion; import com.authlete.common.conf.AuthleteConfiguration; import com.authlete.common.dto.*; @@ -181,21 +183,21 @@ private String createCredentials(AuthleteConfiguration configuration) private TResponse callGetApi( - String path, Class responseClass, Map params) + String path, Class responseClass, Map params, Options options) { - return callGetApi(mAuth, path, responseClass, params); + return callGetApi(mAuth, path, responseClass, params, options); } - private Void callDeleteApi(String path) + private Void callDeleteApi(String path, Options options) { - return callDeleteApi(mAuth, path); + return callDeleteApi(mAuth, path, options); } - private TResponse callPostApi(String path, Object request, Class responseClass) + private TResponse callPostApi(String path, Object request, Class responseClass, Options options) { - return callPostApi(mAuth, path, request, responseClass); + return callPostApi(mAuth, path, request, responseClass, options); } @@ -205,6 +207,7 @@ private static abstract class ApiCaller implements AuthleteApiCall mResponseClass; protected final Map mParams = new LinkedHashMap<>(); + protected Options mOptions; ApiCaller(Class responseClass, Object request, String path) @@ -227,6 +230,14 @@ public ApiCaller addParam(String name, Object... values) return this; } + + + public ApiCaller setOptions(Options options) + { + mOptions = options; + + return this; + } } @@ -247,7 +258,7 @@ private class DeleteApiCaller extends ApiCaller @Override public Void call() { - return callDeleteApi(mPath); + return callDeleteApi(mPath, mOptions); } } @@ -269,7 +280,7 @@ private class GetApiCaller extends ApiCaller @Override public TResponse call() { - return callGetApi(mPath, mResponseClass, mParams); + return callGetApi(mPath, mResponseClass, mParams, mOptions); } } @@ -291,7 +302,7 @@ private class PostApiCaller extends ApiCaller @Override public TResponse call() { - return callPostApi(mPath, mRequest, mResponseClass); + return callPostApi(mPath, mRequest, mResponseClass, mOptions); } } @@ -300,11 +311,12 @@ public TResponse call() * Call {@code /api/{serviceId}/auth/authorization} API. */ @Override - public AuthorizationResponse authorization(AuthorizationRequest request) throws AuthleteApiException + public AuthorizationResponse authorization(AuthorizationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - AuthorizationResponse.class, request, AUTH_AUTHORIZATION_API_PATH, mServiceId)); + AuthorizationResponse.class, request, AUTH_AUTHORIZATION_API_PATH, mServiceId) + .setOptions(options)); } @@ -312,11 +324,12 @@ public AuthorizationResponse authorization(AuthorizationRequest request) throws * Call {@code /api/{serviceId}/auth/authorization/fail} API. */ @Override - public AuthorizationFailResponse authorizationFail(AuthorizationFailRequest request) throws AuthleteApiException + public AuthorizationFailResponse authorizationFail(AuthorizationFailRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - AuthorizationFailResponse.class, request, AUTH_AUTHORIZATION_FAIL_API_PATH, mServiceId)); + AuthorizationFailResponse.class, request, AUTH_AUTHORIZATION_FAIL_API_PATH, mServiceId) + .setOptions(options)); } @@ -324,11 +337,12 @@ public AuthorizationFailResponse authorizationFail(AuthorizationFailRequest requ * Call {@code /api/{serviceId}/auth/authorization/issue} API. */ @Override - public AuthorizationIssueResponse authorizationIssue(AuthorizationIssueRequest request) throws AuthleteApiException + public AuthorizationIssueResponse authorizationIssue(AuthorizationIssueRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - AuthorizationIssueResponse.class, request, AUTH_AUTHORIZATION_ISSUE_API_PATH, mServiceId)); + AuthorizationIssueResponse.class, request, AUTH_AUTHORIZATION_ISSUE_API_PATH, mServiceId) + .setOptions(options)); } @@ -336,11 +350,12 @@ public AuthorizationIssueResponse authorizationIssue(AuthorizationIssueRequest r * Call {@code /api/{serviceId}/auth/token} API. */ @Override - public TokenResponse token(TokenRequest request) throws AuthleteApiException + public TokenResponse token(TokenRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - TokenResponse.class, request, AUTH_TOKEN_API_PATH, mServiceId)); + TokenResponse.class, request, AUTH_TOKEN_API_PATH, mServiceId) + .setOptions(options)); } @@ -348,11 +363,12 @@ public TokenResponse token(TokenRequest request) throws AuthleteApiException * Call {@code /api/{serviceId}/auth/token/create} API. */ @Override - public TokenCreateResponse tokenCreate(TokenCreateRequest request) throws AuthleteApiException + public TokenCreateResponse tokenCreate(TokenCreateRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - TokenCreateResponse.class, request, AUTH_TOKEN_CREATE_API_PATH, mServiceId)); + TokenCreateResponse.class, request, AUTH_TOKEN_CREATE_API_PATH, mServiceId) + .setOptions(options)); } @@ -360,11 +376,12 @@ public TokenCreateResponse tokenCreate(TokenCreateRequest request) throws Authle * Call /api/{serviceId}/auth/token/delete/{token} API. */ @Override - public void tokenDelete(String token) throws AuthleteApiException + public void tokenDelete(String token, Options options) throws AuthleteApiException { executeApiCall( new DeleteApiCaller( - AUTH_TOKEN_DELETE_API_PATH, mServiceId, token)); + AUTH_TOKEN_DELETE_API_PATH, mServiceId, token) + .setOptions(options)); } @@ -372,11 +389,12 @@ public void tokenDelete(String token) throws AuthleteApiException * Call {@code /api/{serviceId}/auth/token/fail} API. */ @Override - public TokenFailResponse tokenFail(TokenFailRequest request) throws AuthleteApiException + public TokenFailResponse tokenFail(TokenFailRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - TokenFailResponse.class, request, AUTH_TOKEN_FAIL_API_PATH, mServiceId)); + TokenFailResponse.class, request, AUTH_TOKEN_FAIL_API_PATH, mServiceId) + .setOptions(options)); } @@ -384,11 +402,12 @@ public TokenFailResponse tokenFail(TokenFailRequest request) throws AuthleteApiE * Call {@code /api/{serviceId}/auth/token/issue} API. */ @Override - public TokenIssueResponse tokenIssue(TokenIssueRequest request) throws AuthleteApiException + public TokenIssueResponse tokenIssue(TokenIssueRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - TokenIssueResponse.class, request, AUTH_TOKEN_ISSUE_API_PATH, mServiceId)); + TokenIssueResponse.class, request, AUTH_TOKEN_ISSUE_API_PATH, mServiceId) + .setOptions(options)); } @@ -396,11 +415,12 @@ public TokenIssueResponse tokenIssue(TokenIssueRequest request) throws AuthleteA * Call {@code /api/{serviceId}/auth/token/revoke} API. */ @Override - public TokenRevokeResponse tokenRevoke(TokenRevokeRequest request) throws AuthleteApiException + public TokenRevokeResponse tokenRevoke(TokenRevokeRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - TokenRevokeResponse.class, request, AUTH_TOKEN_REVOKE_API_PATH, mServiceId)); + TokenRevokeResponse.class, request, AUTH_TOKEN_REVOKE_API_PATH, mServiceId) + .setOptions(options)); } @@ -408,87 +428,90 @@ public TokenRevokeResponse tokenRevoke(TokenRevokeRequest request) throws Authle * Call {@code /api/{serviceId}/auth/token/update} API. */ @Override - public TokenUpdateResponse tokenUpdate(TokenUpdateRequest request) throws AuthleteApiException + public TokenUpdateResponse tokenUpdate(TokenUpdateRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - TokenUpdateResponse.class, request, AUTH_TOKEN_UPDATE_API_PATH, mServiceId)); + TokenUpdateResponse.class, request, AUTH_TOKEN_UPDATE_API_PATH, mServiceId) + .setOptions(options)); } @Override - public TokenListResponse getTokenList() throws AuthleteApiException + public TokenListResponse getTokenList(Options options) throws AuthleteApiException { - return getTokenList(null, null, 0, 0, false, TokenStatus.ALL); + return getTokenList(null, null, 0, 0, false, TokenStatus.ALL, options); } @Override - public TokenListResponse getTokenList(TokenStatus tokenStatus) throws AuthleteApiException + public TokenListResponse getTokenList(TokenStatus tokenStatus, Options options) throws AuthleteApiException { - return getTokenList(null, null, 0, 0, false, tokenStatus); + return getTokenList(null, null, 0, 0, false, tokenStatus, options); } @Override - public TokenListResponse getTokenList(String clientIdentifier, String subject) throws AuthleteApiException + public TokenListResponse getTokenList(String clientIdentifier, String subject, Options options) throws AuthleteApiException { - return getTokenList(clientIdentifier, subject, 0, 0, false, TokenStatus.ALL); + return getTokenList(clientIdentifier, subject, 0, 0, false, TokenStatus.ALL, options); } @Override - public TokenListResponse getTokenList(String clientIdentifier, String subject, TokenStatus tokenStatus) throws AuthleteApiException + public TokenListResponse getTokenList(String clientIdentifier, String subject, TokenStatus tokenStatus, Options options) throws AuthleteApiException { - return getTokenList(clientIdentifier, subject, 0, 0, false, tokenStatus); + return getTokenList(clientIdentifier, subject, 0, 0, false, tokenStatus, options); } @Override - public TokenListResponse getTokenList(int start, int end) throws AuthleteApiException + public TokenListResponse getTokenList(int start, int end, Options options) throws AuthleteApiException { - return getTokenList(null, null, start, end, true, TokenStatus.ALL); + return getTokenList(null, null, start, end, true, TokenStatus.ALL, options); } @Override - public TokenListResponse getTokenList(int start, int end, TokenStatus tokenStatus) throws AuthleteApiException + public TokenListResponse getTokenList(int start, int end, TokenStatus tokenStatus, Options options) throws AuthleteApiException { - return getTokenList(null, null, start, end, true, tokenStatus); + return getTokenList(null, null, start, end, true, tokenStatus, options); } @Override - public TokenListResponse getTokenList(String clientIdentifier, String subject, int start, int end) throws AuthleteApiException + public TokenListResponse getTokenList(String clientIdentifier, String subject, int start, int end, Options options) throws AuthleteApiException { - return getTokenList(clientIdentifier, subject, start, end, true, TokenStatus.ALL); + return getTokenList(clientIdentifier, subject, start, end, true, TokenStatus.ALL, options); } @Override - public TokenListResponse getTokenList(String clientIdentifier, String subject, int start, int end, TokenStatus tokenStatus) throws AuthleteApiException + public TokenListResponse getTokenList(String clientIdentifier, String subject, int start, int end, TokenStatus tokenStatus, Options options) throws AuthleteApiException { - return getTokenList(clientIdentifier, subject, start, end, true, tokenStatus); + return getTokenList(clientIdentifier, subject, start, end, true, tokenStatus, options); } private TokenListResponse getTokenList( final String clientIdentifier, final String subject, - final int start, final int end, final boolean rangeGiven, TokenStatus tokenStatus) throws AuthleteApiException + final int start, final int end, final boolean rangeGiven, TokenStatus tokenStatus, + Options options) throws AuthleteApiException { return executeApiCall(new AuthleteApiCall() { @Override public TokenListResponse call() { - return callGetTokenList(clientIdentifier, subject, start, end, rangeGiven, tokenStatus); + return callGetTokenList(clientIdentifier, subject, start, end, rangeGiven, tokenStatus, options); } }); } private TokenListResponse callGetTokenList( - String clientIdentifier, String subject, int start, int end, boolean rangeGiven, TokenStatus tokenStatus) + String clientIdentifier, String subject, int start, int end, boolean rangeGiven, + TokenStatus tokenStatus, Options options) { String path = String.format(AUTH_TOKEN_GET_LIST_API_PATH, mServiceId); @@ -512,10 +535,13 @@ private TokenListResponse callGetTokenList( target = target.queryParam("tokenStatus", tokenStatus.toString()); // FIXME: it feels weird that this is in its own space instead of the caller classes, is there a reason for that? - return wrapWithDpop(target + Builder builder = wrapWithDpop(target .request(APPLICATION_JSON_TYPE), AUTH_TOKEN_GET_LIST_API_PATH, "GET") - .header(AUTHORIZATION, mAuth) - .get(TokenListResponse.class); + .header(AUTHORIZATION, mAuth); + + setCustomRequestHeaders(builder, options); + + return builder.get(TokenListResponse.class); } @@ -523,11 +549,12 @@ private TokenListResponse callGetTokenList( * Call {@code /api/{serviceId}/auth/revocation} API. */ @Override - public RevocationResponse revocation(RevocationRequest request) throws AuthleteApiException + public RevocationResponse revocation(RevocationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - RevocationResponse.class, request, AUTH_REVOCATION_API_PATH, mServiceId)); + RevocationResponse.class, request, AUTH_REVOCATION_API_PATH, mServiceId) + .setOptions(options)); } @@ -535,11 +562,12 @@ public RevocationResponse revocation(RevocationRequest request) throws AuthleteA * Call {@code /api/{serviceId}/auth/userinfo} API. */ @Override - public UserInfoResponse userinfo(UserInfoRequest request) throws AuthleteApiException + public UserInfoResponse userinfo(UserInfoRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - UserInfoResponse.class, request, AUTH_USERINFO_API_PATH, mServiceId)); + UserInfoResponse.class, request, AUTH_USERINFO_API_PATH, mServiceId) + .setOptions(options)); } @@ -547,11 +575,12 @@ public UserInfoResponse userinfo(UserInfoRequest request) throws AuthleteApiExce * Call {@code /api/{serviceId}/auth/userinfo/issue} API. */ @Override - public UserInfoIssueResponse userinfoIssue(UserInfoIssueRequest request) throws AuthleteApiException + public UserInfoIssueResponse userinfoIssue(UserInfoIssueRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - UserInfoIssueResponse.class, request, AUTH_USERINFO_ISSUE_API_PATH, mServiceId)); + UserInfoIssueResponse.class, request, AUTH_USERINFO_ISSUE_API_PATH, mServiceId) + .setOptions(options)); } @@ -559,11 +588,12 @@ public UserInfoIssueResponse userinfoIssue(UserInfoIssueRequest request) throws * Call {@code /api/{serviceId}/auth/introspection} API. */ @Override - public IntrospectionResponse introspection(IntrospectionRequest request) throws AuthleteApiException + public IntrospectionResponse introspection(IntrospectionRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - IntrospectionResponse.class, request, AUTH_INTROSPECTION_API_PATH, mServiceId)); + IntrospectionResponse.class, request, AUTH_INTROSPECTION_API_PATH, mServiceId) + .setOptions(options)); } @@ -572,11 +602,12 @@ public IntrospectionResponse introspection(IntrospectionRequest request) throws */ @Override public StandardIntrospectionResponse standardIntrospection( - StandardIntrospectionRequest request) throws AuthleteApiException + StandardIntrospectionRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - StandardIntrospectionResponse.class, request, AUTH_INTROSPECTION_STANDARD_API_PATH, mServiceId)); + StandardIntrospectionResponse.class, request, AUTH_INTROSPECTION_STANDARD_API_PATH, mServiceId) + .setOptions(options)); } @@ -584,11 +615,12 @@ public StandardIntrospectionResponse standardIntrospection( * Call {@code /api/service/create} API. */ @Override - public Service createService(Service service) throws AuthleteApiException + public Service createService(Service service, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - Service.class, service, SERVICE_CREATE_API_PATH)); + Service.class, service, SERVICE_CREATE_API_PATH) + .setOptions(options)); } @@ -607,11 +639,11 @@ public Service createServie(Service service) throws AuthleteApiException * Call /api/{serviceId}/service/delete/ API. */ @Override - public void deleteService(long apiKey) throws AuthleteApiException + public void deleteService(long apiKey, Options options) throws AuthleteApiException { executeApiCall( - new DeleteApiCaller( - SERVICE_DELETE_API_PATH, apiKey)); + new DeleteApiCaller(SERVICE_DELETE_API_PATH, apiKey) + .setOptions(options)); } @@ -619,11 +651,12 @@ public void deleteService(long apiKey) throws AuthleteApiException * Call /api/{serviceId}/service/get API. */ @Override - public Service getService(long apiKey) throws AuthleteApiException + public Service getService(long apiKey, Options options) throws AuthleteApiException { return executeApiCall( new GetApiCaller( - Service.class, SERVICE_GET_API_PATH, apiKey)); + Service.class, SERVICE_GET_API_PATH, apiKey) + .setOptions(options)); } @@ -631,28 +664,28 @@ public Service getService(long apiKey) throws AuthleteApiException * Call {@code /api/service/get/list} API. */ @Override - public ServiceListResponse getServiceList() throws AuthleteApiException + public ServiceListResponse getServiceList(Options options) throws AuthleteApiException { - return getServiceList(0, 0, false); + return getServiceList(0, 0, false, options); } @Override - public ServiceListResponse getServiceList(int start, int end) throws AuthleteApiException + public ServiceListResponse getServiceList(int start, int end, Options options) throws AuthleteApiException { - return getServiceList(start, end, true); + return getServiceList(start, end, true, options); } private ServiceListResponse getServiceList( - final int start, final int end, final boolean rangeGiven) throws AuthleteApiException + final int start, final int end, final boolean rangeGiven, Options options) throws AuthleteApiException { return executeApiCall(new AuthleteApiCall() { @Override public ServiceListResponse call() { - return callGetServiceList(start, end, rangeGiven); + return callGetServiceList(start, end, rangeGiven, options); } }); } @@ -661,7 +694,7 @@ public ServiceListResponse call() /** * Call /service/get/list. */ - private ServiceListResponse callGetServiceList(int start, int end, boolean rangeGiven) + private ServiceListResponse callGetServiceList(int start, int end, boolean rangeGiven, Options options) { WebTarget target = getTarget().path(SERVICE_GET_LIST_API_PATH); @@ -671,10 +704,13 @@ private ServiceListResponse callGetServiceList(int start, int end, boolean range } // FIXME: it feels strange that this doesn't use the caller structures above - return wrapWithDpop(target + Builder builder = wrapWithDpop(target .request(APPLICATION_JSON_TYPE), SERVICE_GET_LIST_API_PATH, "GET") - .header(AUTHORIZATION, mAuth) - .get(ServiceListResponse.class); + .header(AUTHORIZATION, mAuth); + + setCustomRequestHeaders(builder, options); + + return builder.get(ServiceListResponse.class); } @@ -682,11 +718,12 @@ private ServiceListResponse callGetServiceList(int start, int end, boolean range * Call /api/{serviceId}/service/update/ API. */ @Override - public Service updateService(final Service service) throws AuthleteApiException + public Service updateService(final Service service, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - Service.class, service, SERVICE_UPDATE_API_PATH, service.getApiKey())); + Service.class, service, SERVICE_UPDATE_API_PATH, service.getApiKey()) + .setOptions(options)); } @@ -694,11 +731,12 @@ public Service updateService(final Service service) throws AuthleteApiException * Call {@code /api/{serviceId}/service/jwks/get} API */ @Override - public String getServiceJwks() throws AuthleteApiException + public String getServiceJwks(Options options) throws AuthleteApiException { return executeApiCall( new GetApiCaller( - String.class, SERVICE_JWKS_GET_API_PATH, mServiceId)); + String.class, SERVICE_JWKS_GET_API_PATH, mServiceId) + .setOptions(options)); } @@ -706,13 +744,14 @@ public String getServiceJwks() throws AuthleteApiException * Call {@code /api/{serviceId}/service/jwks/get} API */ @Override - public String getServiceJwks(boolean pretty, boolean includePrivateKeys) throws AuthleteApiException + public String getServiceJwks(boolean pretty, boolean includePrivateKeys, Options options) throws AuthleteApiException { return executeApiCall( new GetApiCaller( String.class, SERVICE_JWKS_GET_API_PATH, mServiceId) .addParam("pretty", pretty) - .addParam("includePrivateKeys", includePrivateKeys)); + .addParam("includePrivateKeys", includePrivateKeys) + .setOptions(options)); } @@ -720,11 +759,12 @@ public String getServiceJwks(boolean pretty, boolean includePrivateKeys) throws * Call {@code /api/{serviceId}/service/configuration} API */ @Override - public String getServiceConfiguration() throws AuthleteApiException + public String getServiceConfiguration(Options options) throws AuthleteApiException { return executeApiCall( new GetApiCaller( - String.class, SERVICE_CONFIGURATION_API_PATH, mServiceId)); + String.class, SERVICE_CONFIGURATION_API_PATH, mServiceId) + .setOptions(options)); } @@ -732,12 +772,13 @@ public String getServiceConfiguration() throws AuthleteApiException * Call {@code /api/{serviceId}/service/configuration} API */ @Override - public String getServiceConfiguration(boolean pretty) throws AuthleteApiException + public String getServiceConfiguration(boolean pretty, Options options) throws AuthleteApiException { return executeApiCall( new GetApiCaller( String.class, SERVICE_CONFIGURATION_API_PATH, mServiceId) - .addParam("pretty", pretty)); + .addParam("pretty", pretty) + .setOptions(options)); } @@ -745,11 +786,12 @@ public String getServiceConfiguration(boolean pretty) throws AuthleteApiExceptio * Call {@code /api/{serviceId}/service/configuration} API */ @Override - public String getServiceConfiguration(ServiceConfigurationRequest request) throws AuthleteApiException + public String getServiceConfiguration(ServiceConfigurationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - String.class, request, SERVICE_CONFIGURATION_API_PATH, mServiceId)); + String.class, request, SERVICE_CONFIGURATION_API_PATH, mServiceId) + .setOptions(options)); } @@ -757,11 +799,12 @@ public String getServiceConfiguration(ServiceConfigurationRequest request) throw * Call {@code /api/{serviceId}/client/create} API. */ @Override - public Client createClient(Client client) throws AuthleteApiException + public Client createClient(Client client, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - Client.class, client, CLIENT_CREATE_API_PATH, mServiceId)); + Client.class, client, CLIENT_CREATE_API_PATH, mServiceId) + .setOptions(options)); } @@ -769,11 +812,12 @@ public Client createClient(Client client) throws AuthleteApiException * Call {@code /api/{serviceId}/client/registration} API. */ @Override - public ClientRegistrationResponse dynamicClientRegister(ClientRegistrationRequest request) throws AuthleteApiException + public ClientRegistrationResponse dynamicClientRegister(ClientRegistrationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_API_PATH, mServiceId)); + ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_API_PATH, mServiceId) + .setOptions(options)); } @@ -781,11 +825,12 @@ public ClientRegistrationResponse dynamicClientRegister(ClientRegistrationReques * Call {@code /api/{serviceId}/client/registration/get} API. */ @Override - public ClientRegistrationResponse dynamicClientGet(ClientRegistrationRequest request) throws AuthleteApiException + public ClientRegistrationResponse dynamicClientGet(ClientRegistrationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_GET_API_PATH, mServiceId)); + ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_GET_API_PATH, mServiceId) + .setOptions(options)); } @@ -793,11 +838,12 @@ public ClientRegistrationResponse dynamicClientGet(ClientRegistrationRequest req * Call {@code /api/{serviceId}/client/registration/update} API. */ @Override - public ClientRegistrationResponse dynamicClientUpdate(ClientRegistrationRequest request) throws AuthleteApiException + public ClientRegistrationResponse dynamicClientUpdate(ClientRegistrationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_UPDATE_API_PATH, mServiceId)); + ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_UPDATE_API_PATH, mServiceId) + .setOptions(options)); } @@ -805,11 +851,12 @@ public ClientRegistrationResponse dynamicClientUpdate(ClientRegistrationRequest * Call {@code /api/{serviceId}/client/registration/delete} API. */ @Override - public ClientRegistrationResponse dynamicClientDelete(ClientRegistrationRequest request) throws AuthleteApiException + public ClientRegistrationResponse dynamicClientDelete(ClientRegistrationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_DELETE_API_PATH, mServiceId)); + ClientRegistrationResponse.class, request, CLIENT_REGISTRATION_DELETE_API_PATH, mServiceId) + .setOptions(options)); } @@ -817,9 +864,9 @@ public ClientRegistrationResponse dynamicClientDelete(ClientRegistrationRequest * Call /api/{serviceId}/client/delete/{clientId} API. */ @Override - public void deleteClient(long clientId) throws AuthleteApiException + public void deleteClient(long clientId, Options options) throws AuthleteApiException { - deleteClient(String.valueOf(clientId)); + deleteClient(String.valueOf(clientId), options); } @@ -827,11 +874,12 @@ public void deleteClient(long clientId) throws AuthleteApiException * Call /api/{serviceId}/client/delete/{clientId} API. */ @Override - public void deleteClient(String clientId) throws AuthleteApiException + public void deleteClient(String clientId, Options options) throws AuthleteApiException { executeApiCall( new DeleteApiCaller( - CLIENT_DELETE_API_PATH, mServiceId, clientId)); + CLIENT_DELETE_API_PATH, mServiceId, clientId) + .setOptions(options)); } @@ -839,9 +887,9 @@ public void deleteClient(String clientId) throws AuthleteApiException * Call /api/{serviceId}/client/get/{clientId} API. */ @Override - public Client getClient(long clientId) throws AuthleteApiException + public Client getClient(long clientId, Options options) throws AuthleteApiException { - return getClient(String.valueOf(clientId)); + return getClient(String.valueOf(clientId), options); } @@ -849,11 +897,12 @@ public Client getClient(long clientId) throws AuthleteApiException * Call /api/{serviceId}/client/get/{clientId} API. */ @Override - public Client getClient(String clientId) throws AuthleteApiException + public Client getClient(String clientId, Options options) throws AuthleteApiException { return executeApiCall( new GetApiCaller( - Client.class, CLIENT_GET_API_PATH, mServiceId, clientId)); + Client.class, CLIENT_GET_API_PATH, mServiceId, clientId) + .setOptions(options)); } @@ -861,48 +910,48 @@ public Client getClient(String clientId) throws AuthleteApiException * Call {@code /api/{serviceId}/client/get/list} API. */ @Override - public ClientListResponse getClientList() throws AuthleteApiException + public ClientListResponse getClientList(Options options) throws AuthleteApiException { - return getClientList(null, 0, 0, false); + return getClientList(null, 0, 0, false, options); } @Override - public ClientListResponse getClientList(String developer) throws AuthleteApiException + public ClientListResponse getClientList(String developer, Options options) throws AuthleteApiException { - return getClientList(developer, 0, 0, false); + return getClientList(developer, 0, 0, false, options); } @Override - public ClientListResponse getClientList(int start, int end) throws AuthleteApiException + public ClientListResponse getClientList(int start, int end, Options options) throws AuthleteApiException { - return getClientList(null, start, end, true); + return getClientList(null, start, end, true, options); } @Override - public ClientListResponse getClientList(String developer, int start, int end) throws AuthleteApiException + public ClientListResponse getClientList(String developer, int start, int end, Options options) throws AuthleteApiException { - return getClientList(developer, start, end, true); + return getClientList(developer, start, end, true, options); } private ClientListResponse getClientList( - final String developer, final int start, final int end, final boolean rangeGiven) throws AuthleteApiException + final String developer, final int start, final int end, final boolean rangeGiven, Options options) throws AuthleteApiException { return executeApiCall(new AuthleteApiCall() { @Override public ClientListResponse call() { - return callGetClientList(developer, start, end, rangeGiven); + return callGetClientList(developer, start, end, rangeGiven, options); } }); } - private ClientListResponse callGetClientList(String developer, int start, int end, boolean rangeGiven) + private ClientListResponse callGetClientList(String developer, int start, int end, boolean rangeGiven, Options options) { String path = String.format(CLIENT_GET_LIST_API_PATH, mServiceId); @@ -919,10 +968,13 @@ private ClientListResponse callGetClientList(String developer, int start, int en } // FIXME: this seems weird that it's not the same caller structure as others - return wrapWithDpop(target + Builder builder = wrapWithDpop(target .request(APPLICATION_JSON_TYPE), CLIENT_GET_LIST_API_PATH, "GET") - .header(AUTHORIZATION, mAuth) - .get(ClientListResponse.class); + .header(AUTHORIZATION, mAuth); + + setCustomRequestHeaders(builder, options); + + return builder.get(ClientListResponse.class); } @@ -930,25 +982,26 @@ private ClientListResponse callGetClientList(String developer, int start, int en * Call /api/{serviceId}/client/update/{clientId} API. */ @Override - public Client updateClient(Client client) throws AuthleteApiException + public Client updateClient(Client client, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - Client.class, client, CLIENT_UPDATE_API_PATH, mServiceId, client.getClientId())); + Client.class, client, CLIENT_UPDATE_API_PATH, mServiceId, client.getClientId()) + .setOptions(options)); } - /** * Call /api/{serviceId}/client/extension/requestable_scopes/get/{clientId} API. */ @Override - public String[] getRequestableScopes(long clientId) throws AuthleteApiException + public String[] getRequestableScopes(long clientId, Options options) throws AuthleteApiException { // Call the API. RequestableScopes response = executeApiCall( new GetApiCaller( - RequestableScopes.class, REQUESTABLE_SCOPES_GET_API_PATH, mServiceId, clientId)); + RequestableScopes.class, REQUESTABLE_SCOPES_GET_API_PATH, mServiceId, clientId) + .setOptions(options)); if (response != null) { @@ -963,7 +1016,7 @@ public String[] getRequestableScopes(long clientId) throws AuthleteApiException @Override - public String[] setRequestableScopes(long clientId, String[] scopes) throws AuthleteApiException + public String[] setRequestableScopes(long clientId, String[] scopes, Options options) throws AuthleteApiException { // Prepare a request body. RequestableScopes request = new RequestableScopes().setRequestableScopes(scopes); @@ -971,7 +1024,8 @@ public String[] setRequestableScopes(long clientId, String[] scopes) throws Auth // Call the API. RequestableScopes response = executeApiCall( new PostApiCaller( - RequestableScopes.class, request, REQUESTABLE_SCOPES_UPDATE_API_PATH, mServiceId, clientId)); + RequestableScopes.class, request, REQUESTABLE_SCOPES_UPDATE_API_PATH, mServiceId, clientId) + .setOptions(options)); if (response != null) { @@ -989,16 +1043,17 @@ public String[] setRequestableScopes(long clientId, String[] scopes) throws Auth * Call /api/{serviceId}/client/extension/requestable_scopes/delete/{clientId} API. */ @Override - public void deleteRequestableScopes(long clientId) throws AuthleteApiException + public void deleteRequestableScopes(long clientId, Options options) throws AuthleteApiException { executeApiCall( new DeleteApiCaller( - REQUESTABLE_SCOPES_DELETE_API_PATH, mServiceId, clientId)); + REQUESTABLE_SCOPES_DELETE_API_PATH, mServiceId, clientId) + .setOptions(options)); } @Override - public GrantedScopesGetResponse getGrantedScopes(long clientId, String subject) + public GrantedScopesGetResponse getGrantedScopes(long clientId, String subject, Options options) { // Prepare a request body. GrantedScopesRequest request = new GrantedScopesRequest(subject); @@ -1006,19 +1061,21 @@ public GrantedScopesGetResponse getGrantedScopes(long clientId, String subject) // Call the API. return executeApiCall( new PostApiCaller( - GrantedScopesGetResponse.class, request, GRANTED_SCOPES_GET_API_PATH, mServiceId, clientId)); + GrantedScopesGetResponse.class, request, GRANTED_SCOPES_GET_API_PATH, mServiceId, clientId) + .setOptions(options)); } @Override - public void deleteGrantedScopes(long clientId, String subject) + public void deleteGrantedScopes(long clientId, String subject, Options options) { // Prepare a request body. GrantedScopesRequest request = new GrantedScopesRequest(subject); executeApiCall( new PostApiCaller( - ApiResponse.class, request, GRANTED_SCOPES_DELETE_API_PATH, mServiceId, clientId)); + ApiResponse.class, request, GRANTED_SCOPES_DELETE_API_PATH, mServiceId, clientId) + .setOptions(options)); } @@ -1049,61 +1106,68 @@ public void setSubject(String subject) @Override - public void deleteClientAuthorization(long clientId, String subject) throws AuthleteApiException + public void deleteClientAuthorization(long clientId, String subject, Options options) throws AuthleteApiException { // Prepare a request body. ClientAuthorizationDeleteRequest request = new ClientAuthorizationDeleteRequest(subject); executeApiCall( new PostApiCaller( - ApiResponse.class, request, CLIENT_AUTHORIZATION_DELETE_API_PATH, mServiceId, clientId)); + ApiResponse.class, request, CLIENT_AUTHORIZATION_DELETE_API_PATH, mServiceId, clientId) + .setOptions(options)); } @Override - public AuthorizedClientListResponse getClientAuthorizationList(ClientAuthorizationGetListRequest request) throws AuthleteApiException + public AuthorizedClientListResponse getClientAuthorizationList( + ClientAuthorizationGetListRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - AuthorizedClientListResponse.class, request, CLIENT_AUTHORIZATION_GET_LIST_API_PATH, mServiceId)); + AuthorizedClientListResponse.class, request, CLIENT_AUTHORIZATION_GET_LIST_API_PATH, mServiceId) + .setOptions(options)); } @Override - public void updateClientAuthorization(long clientId, ClientAuthorizationUpdateRequest request) throws AuthleteApiException + public void updateClientAuthorization( + long clientId, ClientAuthorizationUpdateRequest request, Options options) throws AuthleteApiException { executeApiCall( new PostApiCaller( - ApiResponse.class, request, CLIENT_AUTHORIZATION_UPDATE_API_PATH, mServiceId, clientId)); + ApiResponse.class, request, CLIENT_AUTHORIZATION_UPDATE_API_PATH, mServiceId, clientId) + .setOptions(options)); } @Override - public ClientSecretRefreshResponse refreshClientSecret(long clientId) throws AuthleteApiException + public ClientSecretRefreshResponse refreshClientSecret(long clientId, Options options) throws AuthleteApiException { - return refreshClientSecret(String.valueOf(clientId)); + return refreshClientSecret(String.valueOf(clientId), options); } @Override - public ClientSecretRefreshResponse refreshClientSecret(String clientIdentifier) throws AuthleteApiException + public ClientSecretRefreshResponse refreshClientSecret(String clientIdentifier, Options options) throws AuthleteApiException { return executeApiCall( new GetApiCaller( ClientSecretRefreshResponse.class, - CLIENT_SECRET_REFRESH_API_PATH, mServiceId, clientIdentifier)); + CLIENT_SECRET_REFRESH_API_PATH, mServiceId, clientIdentifier) + .setOptions(options)); } @Override - public ClientSecretUpdateResponse updateClientSecret(long clientId, String clientSecret) throws AuthleteApiException + public ClientSecretUpdateResponse updateClientSecret(long clientId, String clientSecret, Options options) throws AuthleteApiException { - return updateClientSecret(String.valueOf(clientId), clientSecret); + return updateClientSecret(String.valueOf(clientId), clientSecret, options); } @Override - public ClientSecretUpdateResponse updateClientSecret(String clientIdentifier, String clientSecret) throws AuthleteApiException + public ClientSecretUpdateResponse updateClientSecret( + String clientIdentifier, String clientSecret, Options options) throws AuthleteApiException { // Prepare a request body. setClientSecret(String) method // throws IllegalArgumentException if the given client secret @@ -1114,7 +1178,8 @@ public ClientSecretUpdateResponse updateClientSecret(String clientIdentifier, St return executeApiCall( new PostApiCaller( ClientSecretUpdateResponse.class, request, - CLIENT_SECRET_UPDATE_API_PATH, mServiceId, clientIdentifier)); + CLIENT_SECRET_UPDATE_API_PATH, mServiceId, clientIdentifier) + .setOptions(options)); } @@ -1122,11 +1187,12 @@ public ClientSecretUpdateResponse updateClientSecret(String clientIdentifier, St * Call {@code /api/{serviceId}/jose/verify} API. */ @Override - public JoseVerifyResponse verifyJose(JoseVerifyRequest request) throws AuthleteApiException + public JoseVerifyResponse verifyJose(JoseVerifyRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - JoseVerifyResponse.class, request, JOSE_VERIFY_API_PATH, mServiceId)); + JoseVerifyResponse.class, request, JOSE_VERIFY_API_PATH, mServiceId) + .setOptions(options)); } @@ -1134,11 +1200,13 @@ public JoseVerifyResponse verifyJose(JoseVerifyRequest request) throws AuthleteA * Call {@code /api/{serviceId}/backchannel/authentication} API. */ @Override - public BackchannelAuthenticationResponse backchannelAuthentication(BackchannelAuthenticationRequest request) throws AuthleteApiException + public BackchannelAuthenticationResponse backchannelAuthentication( + BackchannelAuthenticationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - BackchannelAuthenticationResponse.class, request, BACKCHANNEL_AUTHENTICATION_API_PATH, mServiceId)); + BackchannelAuthenticationResponse.class, request, BACKCHANNEL_AUTHENTICATION_API_PATH, mServiceId) + .setOptions(options)); } @@ -1146,11 +1214,13 @@ public BackchannelAuthenticationResponse backchannelAuthentication(BackchannelAu * Call {@code /api/{serviceId}/backchannel/authentication/issue} API. */ @Override - public BackchannelAuthenticationIssueResponse backchannelAuthenticationIssue(BackchannelAuthenticationIssueRequest request) throws AuthleteApiException + public BackchannelAuthenticationIssueResponse backchannelAuthenticationIssue( + BackchannelAuthenticationIssueRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - BackchannelAuthenticationIssueResponse.class, request, BACKCHANNEL_AUTHENTICATION_ISSUE_API_PATH, mServiceId)); + BackchannelAuthenticationIssueResponse.class, request, BACKCHANNEL_AUTHENTICATION_ISSUE_API_PATH, mServiceId) + .setOptions(options)); } @@ -1158,11 +1228,13 @@ public BackchannelAuthenticationIssueResponse backchannelAuthenticationIssue(Bac * Call {@code /api/{serviceId}/backchannel/authentication/fail} API. */ @Override - public BackchannelAuthenticationFailResponse backchannelAuthenticationFail(BackchannelAuthenticationFailRequest request) throws AuthleteApiException + public BackchannelAuthenticationFailResponse backchannelAuthenticationFail( + BackchannelAuthenticationFailRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - BackchannelAuthenticationFailResponse.class, request, BACKCHANNEL_AUTHENTICATION_FAIL_API_PATH, mServiceId)); + BackchannelAuthenticationFailResponse.class, request, BACKCHANNEL_AUTHENTICATION_FAIL_API_PATH, mServiceId) + .setOptions(options)); } @@ -1170,11 +1242,13 @@ public BackchannelAuthenticationFailResponse backchannelAuthenticationFail(Backc * Call {@code /api/{serviceId}/backchannel/authentication/complete} API. */ @Override - public BackchannelAuthenticationCompleteResponse backchannelAuthenticationComplete(BackchannelAuthenticationCompleteRequest request) throws AuthleteApiException + public BackchannelAuthenticationCompleteResponse backchannelAuthenticationComplete( + BackchannelAuthenticationCompleteRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - BackchannelAuthenticationCompleteResponse.class, request, BACKCHANNEL_AUTHENTICATION_COMPLETE_API_PATH, mServiceId)); + BackchannelAuthenticationCompleteResponse.class, request, BACKCHANNEL_AUTHENTICATION_COMPLETE_API_PATH, mServiceId) + .setOptions(options)); } @@ -1182,11 +1256,13 @@ public BackchannelAuthenticationCompleteResponse backchannelAuthenticationComple * Call {@code /api/{serviceId}/device/authorization} API. */ @Override - public DeviceAuthorizationResponse deviceAuthorization(DeviceAuthorizationRequest request) throws AuthleteApiException + public DeviceAuthorizationResponse deviceAuthorization( + DeviceAuthorizationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - DeviceAuthorizationResponse.class, request, DEVICE_AUTHORIZATION_API_PATH, mServiceId)); + DeviceAuthorizationResponse.class, request, DEVICE_AUTHORIZATION_API_PATH, mServiceId) + .setOptions(options)); } @@ -1194,11 +1270,13 @@ public DeviceAuthorizationResponse deviceAuthorization(DeviceAuthorizationReques * Call {@code /api/{serviceId}/device/complete} API. */ @Override - public DeviceCompleteResponse deviceComplete(DeviceCompleteRequest request) throws AuthleteApiException + public DeviceCompleteResponse deviceComplete( + DeviceCompleteRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - DeviceCompleteResponse.class, request, DEVICE_COMPLETE_API_PATH, mServiceId)); + DeviceCompleteResponse.class, request, DEVICE_COMPLETE_API_PATH, mServiceId) + .setOptions(options)); } @@ -1206,77 +1284,85 @@ public DeviceCompleteResponse deviceComplete(DeviceCompleteRequest request) thro * Call {@code /api/{serviceId}/device/verification} API. */ @Override - public DeviceVerificationResponse deviceVerification(DeviceVerificationRequest request) throws AuthleteApiException + public DeviceVerificationResponse deviceVerification( + DeviceVerificationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - DeviceVerificationResponse.class, request, DEVICE_VERIFICATION_API_PATH, mServiceId)); + DeviceVerificationResponse.class, request, DEVICE_VERIFICATION_API_PATH, mServiceId) + .setOptions(options)); } @Override - public PushedAuthReqResponse pushAuthorizationRequest(PushedAuthReqRequest request) throws AuthleteApiException + public PushedAuthReqResponse pushAuthorizationRequest( + PushedAuthReqRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - PushedAuthReqResponse.class, request, PUSHED_AUTH_REQ_API_PATH, mServiceId)); + PushedAuthReqResponse.class, request, PUSHED_AUTH_REQ_API_PATH, mServiceId) + .setOptions(options)); } @Override - public HskResponse hskCreate(HskCreateRequest request) throws AuthleteApiException + public HskResponse hskCreate(HskCreateRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - HskResponse.class, request, HSK_CREATE_API_PATH, mServiceId)); + HskResponse.class, request, HSK_CREATE_API_PATH, mServiceId) + .setOptions(options)); } @Override - public HskResponse hskDelete(String handle) throws AuthleteApiException + public HskResponse hskDelete(String handle, Options options) throws AuthleteApiException { return executeApiCall( new GetApiCaller( HskResponse.class, - HSK_DELETE_API_PATH, mServiceId, handle)); + HSK_DELETE_API_PATH, mServiceId, handle) + .setOptions(options)); } @Override - public HskResponse hskGet(String handle) throws AuthleteApiException + public HskResponse hskGet(String handle, Options options) throws AuthleteApiException { return executeApiCall( new GetApiCaller( HskResponse.class, - HSK_GET_API_PATH, mServiceId, handle)); + HSK_GET_API_PATH, mServiceId, handle) + .setOptions(options)); } @Override - public HskListResponse hskGetList() throws AuthleteApiException + public HskListResponse hskGetList(Options options) throws AuthleteApiException { return executeApiCall( new GetApiCaller( HskListResponse.class, - HSK_GET_LIST_API_PATH, mServiceId)); + HSK_GET_LIST_API_PATH, mServiceId) + .setOptions(options)); } @Override - public Map echo(Map parameters) throws AuthleteApiException + public Map echo(Map parameters, Options options) throws AuthleteApiException { return executeApiCall(new AuthleteApiCall>() { @Override public Map call() { - return callEcho(parameters); + return callEcho(parameters, options); } }); } - private Map callEcho(Map parameters) + private Map callEcho(Map parameters, Options options) { WebTarget target = getTarget().path(ECHO_API_PATH); @@ -1291,229 +1377,251 @@ private Map callEcho(Map parameters) // The API does not require any authentication, so the code below // does not include '.header(AUTHORIZATION, ...)'. - return target - .request(APPLICATION_JSON_TYPE) - .get(new GenericType>(){}); + Builder builder = target.request(APPLICATION_JSON_TYPE); + + setCustomRequestHeaders(builder, options); + + return builder.get(new GenericType>(){}); } @Override - public GMResponse gm(GMRequest request) throws AuthleteApiException + public GMResponse gm(GMRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( - GMResponse.class, request, GM_API_PATH, mServiceId)); + GMResponse.class, request, GM_API_PATH, mServiceId) + .setOptions(options)); } @Override public void updateClientLockFlag( - String clientIdentifier, boolean clientLocked) throws AuthleteApiException + String clientIdentifier, boolean clientLocked, Options options) throws AuthleteApiException { // Prepare a request body. ClientLockFlagUpdateRequest request = new ClientLockFlagUpdateRequest().setClientLocked(clientLocked); executeApiCall( new PostApiCaller( - ApiResponse.class, request, CLIENT_LOCK_FLAG_UPDATE_API_PATH, mServiceId, clientIdentifier)); + ApiResponse.class, request, CLIENT_LOCK_FLAG_UPDATE_API_PATH, mServiceId, clientIdentifier) + .setOptions(options)); } @Override public FederationConfigurationResponse federationConfiguration( - FederationConfigurationRequest request) throws AuthleteApiException + FederationConfigurationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( FederationConfigurationResponse.class, request, - FEDERATION_CONFIGURATION_API_PATH, mServiceId)); + FEDERATION_CONFIGURATION_API_PATH, mServiceId) + .setOptions(options)); } @Override public FederationRegistrationResponse federationRegistration( - FederationRegistrationRequest request) throws AuthleteApiException + FederationRegistrationRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( FederationRegistrationResponse.class, request, - FEDERATION_REGISTRATION_API_PATH, mServiceId)); + FEDERATION_REGISTRATION_API_PATH, mServiceId) + .setOptions(options)); } @Override public CredentialIssuerMetadataResponse credentialIssuerMetadata( - CredentialIssuerMetadataRequest request) throws AuthleteApiException + CredentialIssuerMetadataRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( CredentialIssuerMetadataResponse.class, request, - VCI_METADATA_API_PATH, mServiceId)); + VCI_METADATA_API_PATH, mServiceId) + .setOptions(options)); } @Override public CredentialJwtIssuerMetadataResponse credentialJwtIssuerMetadata( - CredentialJwtIssuerMetadataRequest request) throws AuthleteApiException + CredentialJwtIssuerMetadataRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( CredentialJwtIssuerMetadataResponse.class, request, - VCI_JWT_ISSUER_API_PATH, mServiceId)); + VCI_JWT_ISSUER_API_PATH, mServiceId) + .setOptions(options)); } @Override public CredentialIssuerJwksResponse credentialIssuerJwks( - CredentialIssuerJwksRequest request) throws AuthleteApiException + CredentialIssuerJwksRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( CredentialIssuerJwksResponse.class, request, - VCI_JWKS_API_PATH, mServiceId)); + VCI_JWKS_API_PATH, mServiceId) + .setOptions(options)); } @Override public CredentialOfferCreateResponse credentialOfferCreate( - CredentialOfferCreateRequest request) throws AuthleteApiException + CredentialOfferCreateRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( CredentialOfferCreateResponse.class, request, - VCI_OFFER_CREATE_API_PATH, mServiceId)); + VCI_OFFER_CREATE_API_PATH, mServiceId) + .setOptions(options)); } @Override public CredentialOfferInfoResponse credentialOfferInfo( - CredentialOfferInfoRequest request) throws AuthleteApiException + CredentialOfferInfoRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( CredentialOfferInfoResponse.class, request, - VCI_OFFER_INFO_API_PATH, mServiceId)); + VCI_OFFER_INFO_API_PATH, mServiceId) + .setOptions(options)); } @Override public CredentialSingleParseResponse credentialSingleParse( - CredentialSingleParseRequest request) throws AuthleteApiException + CredentialSingleParseRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( CredentialSingleParseResponse.class, request, - VCI_SINGLE_PARSE_API_PATH, mServiceId)); + VCI_SINGLE_PARSE_API_PATH, mServiceId) + .setOptions(options)); } @Override public CredentialSingleIssueResponse credentialSingleIssue( - CredentialSingleIssueRequest request) throws AuthleteApiException + CredentialSingleIssueRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( CredentialSingleIssueResponse.class, request, - VCI_SINGLE_ISSUE_API_PATH, mServiceId)); + VCI_SINGLE_ISSUE_API_PATH, mServiceId) + .setOptions(options)); } @Override public CredentialBatchParseResponse credentialBatchParse( - CredentialBatchParseRequest request) throws AuthleteApiException + CredentialBatchParseRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( CredentialBatchParseResponse.class, request, - VCI_BATCH_PARSE_API_PATH, mServiceId)); + VCI_BATCH_PARSE_API_PATH, mServiceId) + .setOptions(options)); } @Override public CredentialBatchIssueResponse credentialBatchIssue( - CredentialBatchIssueRequest request) throws AuthleteApiException + CredentialBatchIssueRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( CredentialBatchIssueResponse.class, request, - VCI_BATCH_ISSUE_API_PATH, mServiceId)); + VCI_BATCH_ISSUE_API_PATH, mServiceId) + .setOptions(options)); } @Override public CredentialDeferredParseResponse credentialDeferredParse( - CredentialDeferredParseRequest request) throws AuthleteApiException + CredentialDeferredParseRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( CredentialDeferredParseResponse.class, request, - VCI_DEFERRED_PARSE_API_PATH, mServiceId)); + VCI_DEFERRED_PARSE_API_PATH, mServiceId) + .setOptions(options)); } @Override public CredentialDeferredIssueResponse credentialDeferredIssue( - CredentialDeferredIssueRequest request) throws AuthleteApiException + CredentialDeferredIssueRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( CredentialDeferredIssueResponse.class, request, - VCI_DEFERRED_ISSUE_API_PATH, mServiceId)); + VCI_DEFERRED_ISSUE_API_PATH, mServiceId) + .setOptions(options)); } @Override public IDTokenReissueResponse idTokenReissue( - IDTokenReissueRequest request) throws AuthleteApiException + IDTokenReissueRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( IDTokenReissueResponse.class, request, - ID_TOKEN_REISSUE_API_PATH, mServiceId)); + ID_TOKEN_REISSUE_API_PATH, mServiceId) + .setOptions(options)); } @Override public AuthorizationTicketInfoResponse authorizationTicketInfo( - AuthorizationTicketInfoRequest request) throws AuthleteApiException + AuthorizationTicketInfoRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( AuthorizationTicketInfoResponse.class, request, - AUTH_AUTHORIZATION_TICKET_INFO_API_PATH, mServiceId)); + AUTH_AUTHORIZATION_TICKET_INFO_API_PATH, mServiceId) + .setOptions(options)); } @Override public AuthorizationTicketUpdateResponse authorizationTicketUpdate( - AuthorizationTicketUpdateRequest request) throws AuthleteApiException + AuthorizationTicketUpdateRequest request, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( AuthorizationTicketUpdateResponse.class, request, - AUTH_AUTHORIZATION_TICKET_UPDATE_API_PATH, mServiceId)); + AUTH_AUTHORIZATION_TICKET_UPDATE_API_PATH, mServiceId) + .setOptions(options)); } @Override public TokenCreateBatchResponse tokenCreateBatch( - TokenCreateRequest[] request, boolean dryRun) throws AuthleteApiException + TokenCreateRequest[] request, boolean dryRun, Options options) throws AuthleteApiException { return executeApiCall( new PostApiCaller( TokenCreateBatchResponse.class, request, TOKEN_CREATE_BATCH_API_PATH, mServiceId) - .addParam("dryRun", dryRun)); + .addParam("dryRun", dryRun) + .setOptions(options)); } @Override public TokenCreateBatchStatusResponse getTokenCreateBatchStatus( - String requestId) throws AuthleteApiException + String requestId, Options options) throws AuthleteApiException { return executeApiCall( new GetApiCaller( TokenCreateBatchStatusResponse.class, - TOKEN_CREATE_BATCH_STATUS_API_PATH, mServiceId, requestId)); + TOKEN_CREATE_BATCH_STATUS_API_PATH, mServiceId, requestId) + .setOptions(options)); } } diff --git a/src/main/java/com/authlete/jakarta/api/AuthleteApiJaxrsImpl.java b/src/main/java/com/authlete/jakarta/api/AuthleteApiJaxrsImpl.java index cfb28ae..001484e 100644 --- a/src/main/java/com/authlete/jakarta/api/AuthleteApiJaxrsImpl.java +++ b/src/main/java/com/authlete/jakarta/api/AuthleteApiJaxrsImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2022 Authlete, Inc. + * Copyright (C) 2014-2025 Authlete, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,17 +17,21 @@ package com.authlete.jakarta.api; +import static jakarta.ws.rs.core.HttpHeaders.ACCEPT; import static jakarta.ws.rs.core.HttpHeaders.AUTHORIZATION; +import static jakarta.ws.rs.core.HttpHeaders.CONTENT_TYPE; import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import java.text.ParseException; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.UUID; import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation; +import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.client.ResponseProcessingException; import jakarta.ws.rs.client.WebTarget; import jakarta.ws.rs.core.MediaType; @@ -35,6 +39,7 @@ import jakarta.ws.rs.core.Response.StatusType; import com.authlete.common.api.AuthleteApi; import com.authlete.common.api.AuthleteApiException; +import com.authlete.common.api.Options; import com.authlete.common.api.Settings; import com.authlete.common.conf.AuthleteConfiguration; import com.nimbusds.jose.JOSEException; @@ -406,7 +411,7 @@ private String extractResponseBody(Response response) protected TResponse callGetApi( - String auth, String path, Class responseClass, Map params) + String auth, String path, Class responseClass, Map params, Options options) { WebTarget webTarget = getTarget().path(path); @@ -418,32 +423,41 @@ protected TResponse callGetApi( } } - return wrapWithDpop(webTarget.request(APPLICATION_JSON_TYPE), path, "GET") - .header(AUTHORIZATION, auth) - .get(responseClass); + Builder builder = wrapWithDpop(webTarget.request(APPLICATION_JSON_TYPE), path, "GET") + .header(AUTHORIZATION, auth); + + setCustomRequestHeaders(builder, options); + + return builder.get(responseClass); } - protected Void callDeleteApi(String auth, String path) + protected Void callDeleteApi(String auth, String path, Options options) { - wrapWithDpop(getTarget() + Builder builder = wrapWithDpop(getTarget() .path(path) .request(), path, "DELETE") - .header(AUTHORIZATION, auth) - .delete(); + .header(AUTHORIZATION, auth); + + setCustomRequestHeaders(builder, options); + + builder.delete(); return null; } protected TResponse callPostApi( - String auth, String path, Object request, Class responseClass) + String auth, String path, Object request, Class responseClass, Options options) { - return wrapWithDpop(getTarget() + Builder builder = wrapWithDpop(getTarget() .path(path) .request(APPLICATION_JSON_TYPE), path, "POST") - .header(AUTHORIZATION, auth) - .post(Entity.entity(request, JSON_UTF8_TYPE), responseClass); + .header(AUTHORIZATION, auth); + + setCustomRequestHeaders(builder, options); + + return builder.post(Entity.entity(request, JSON_UTF8_TYPE), responseClass); } @@ -470,4 +484,45 @@ protected boolean isDpopEnabled() { return mDpopJwk != null; } + + + protected void setCustomRequestHeaders(Builder builder, Options options) + { + if (options == null) + { + return; + } + + // Custom request headers. + Map headers = options.getHeaders(); + + if (headers == null) + { + // No custom request header is specified. + return; + } + + // Add each custom request header to the builder. + for (Entry e : headers.entrySet()) + { + // The key of the header. + String key = e.getKey(); + + // Some header keys are reserved. + if (isReservedRequestHeader(key)) + { + continue; + } + + builder.header(key, e.getValue()); + } + } + + + private static boolean isReservedRequestHeader(String key) + { + return key.equalsIgnoreCase(ACCEPT) || + key.equalsIgnoreCase(AUTHORIZATION) || + key.equalsIgnoreCase(CONTENT_TYPE); + } }