All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.authlete.common.dto.IntrospectionResponse Maven / Gradle / Ivy

/*
 * Copyright (C) 2014-2019 Authlete, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.authlete.common.dto;


import java.net.URI;
import com.authlete.common.util.Utils;


/**
 * Response from Authlete's {@code /auth/introspection} API.
 *
 * 

* Authlete's {@code /auth/introspection} API returns JSON which can * be mapped to this class. The service implementation should retrieve * the value of {@code "action"} from the response and take the following * steps according to the value. *

* *
*
{@link Action#INTERNAL_SERVER_ERROR INTERNAL_SERVER_ERROR}
*
*

* When the value of {@code "action"} is {@code "INTERNAL_SERVER_ERROR"}, * it means that the request from the service implementation was wrong or * that an error occurred in Authlete. *

* *

* In either case, from the viewpoint of the client application, it is an * error on the server side. Therefore, the service implementation should * generate a response to the client application with the HTTP status of * {@code "500 Internal Server Error"}. *

* *

* {@link #getResponseContent()} returns a string which describes the error * in the format of RFC 6750 * (OAuth 2.0 Bearer Token Usage), so if the protected resource of the service * implementation wants to return an error response to the client application * in the way that complies with RFC 6750, the string returned from {@link * #getResponseContent()} can be used as the value of {@code WWW-Authenticate}. *

* *

* The following is an example response which complies with RFC 6750. *

* *
 * HTTP/1.1 500 Internal Server Error
 * WWW-Authenticate: (The value returned from {@link #getResponseContent()})
 * Cache-Control: no-store
 * Pragma: no-cache
*
* *
{@link Action#BAD_REQUEST BAD_REQUEST}
*
*

* When the value of {@code "action"} is {@code "BAD_REQUEST"}, it means * that the request from the client application does not contain an access * token (= the request from the service implementation to Authlete does * not contain {@code "token"} parameter). *

* *

* {@link #getResponseContent()} returns a string which describes the error * in the format of RFC 6750 * (OAuth 2.0 Bearer Token Usage), so if the protected resource of the service * implementation wants to return an error response to the client application * in the way that complies with RFC 6750, the string returned from {@link * #getResponseContent()} can be used as the value of {@code WWW-Authenticate}. *

* *

* The following is an example response which complies with RFC 6750. *

* *
 * HTTP/1.1 400 Bad Request
 * WWW-Authenticate: (The value returned from {@link #getResponseContent()})
 * Cache-Control: no-store
 * Pragma: no-cache
*
* *
{@link Action#UNAUTHORIZED UNAUTHORIZED}
*
*

* When the value of {@code "action"} is {@code "UNAUTHORIZED"}, it means * that the access token does not exist or has expired. Or the client * application associated with the access token does not exist any longer. *

* *

* {@link #getResponseContent()} returns a string which describes the error * in the format of RFC 6750 * (OAuth 2.0 Bearer Token Usage), so if the protected resource of the service * implementation wants to return an error response to the client application * in the way that complies with RFC 6750, the string returned from {@link * #getResponseContent()} can be used as the value of {@code WWW-Authenticate}. *

* *

* The following is an example response which complies with RFC 6750. *

* *
 * HTTP/1.1 401 Unauthorized
 * WWW-Authenticate: (The value returned from {@link #getResponseContent()})
 * Cache-Control: no-store
 * Pragma: no-cache
*
* *
{@link Action#FORBIDDEN FORBIDDEN}
*
*

* When the value of {@code "action"} is {@code "FORBIDDEN"}, it means * that the access token does not cover the required scopes or that the * subject associated with the access token is different from the subject * contained in the request. *

* *

* {@link #getResponseContent()} returns a string which describes the error * in the format of RFC 6750 * (OAuth 2.0 Bearer Token Usage), so if the protected resource of the service * implementation wants to return an error response to the client application * in the way that complies with RFC 6750, the string returned from {@link * #getResponseContent()} can be used as the value of {@code WWW-Authenticate}. *

* *

* The following is an example response which complies with RFC 6750. *

* *
 * HTTP/1.1 403 Forbidden
 * WWW-Authenticate: (The value returned from {@link #getResponseContent()})
 * Cache-Control: no-store
 * Pragma: no-cache
*
* *
{@link Action#OK OK}
*
*

* When the value of {@code "action"} is {@code "OK"}, it means that the * access token which the client application presented is valid (= exists * and has not expired). *

* *

* The service implementation is supposed to return the protected resource * to the client application. *

* *

* When {@code "action"} is {@code "OK"}, {@link #getResponseContent()} * returns {@code "Bearer error=\"invalid_request\""}. This is the * simplest string which can be used as the value of {@code WWW-Authenticate} * header to indicate {@code "400 Bad Request"}. The service implementation * may use this string to tell the client application that the request was * bad. But in such a case, the service should generate a more informative * error message to help developers of client applications. *

* *

* The following is an example error response which complies with RFC 6750. *

* *
 * HTTP/1.1 400 Bad Request
 * WWW-Authenticate: (The value returned from {@link #getResponseContent()})
 * Cache-Control: no-store
 * Pragma: no-cache
*
*
* *

* Basically, {@link #getResponseContent()} returns a string which describes * the error in the format of RFC 6750 (OAuth 2.0 Bearer Token Usage). So, if the service has * selected {@code "Bearer"} as the token type, the string returned from * {@link #getResponseContent()} can be used directly as the value for * {@code WWW-Authenticate}. However, if the service has selected another * different token type, the service has to generate error messages for * itself. *

* *

JWT-based access token

* *

* Since version 2.1, Authlete provides a feature to issue access tokens in * JWT format. This feature can be enabled by setting a non-null value to the * {@code accessTokenSignAlg} property of the service (see the description of * the {@link Service} class for details). {@code /api/auth/introspection} API * can accept access tokens in JWT format. However, note that the API does not * return information contained in a given JWT-based access token but returns * information stored in the database record which corresponds to the given * JWT-based access token. Because attributes of the database record can be * modified after the access token is issued (for example, by using {@code * /api/auth/token/update} API), information returned by {@code * /api/auth/introspection} API and information the given JWT-based access * token holds may be different. *

* * @author Takahiko Kawasaki */ public class IntrospectionResponse extends ApiResponse { private static final long serialVersionUID = 10L; /** * The next action the service implementation should take. */ public enum Action { /** * The request from the service implementation was wrong or * an error occurred in Authlete. The service implementation * should return {@code "500 Internal Server Error"} to the * client application. */ INTERNAL_SERVER_ERROR, /** * The request does not contain an access token. The service * implementation should return {@code "400 Bad Request"} to * the client application. */ BAD_REQUEST, /** * The access token does not exist or has expired. The service * implementation should return {@code "401 Unauthorized"} to * the client application. */ UNAUTHORIZED, /** * The access token does not cover the required scopes. The * service implementation should return {@code "403 Forbidden"} * to the client application. */ FORBIDDEN, /** * The access token is valid. The service implementation should * return the protected resource to the client application. */ OK } private static final String SUMMARY_FORMAT = "action=%s, clientId=%d, subject=%s, existent=%s, " + "usable=%s, sufficient=%s, refreshable=%s, expiresAt=%d, " + "scopes=%s, properties=%s, clientIdAlias=%s, clientIdAliasUsed=%s, " + "confirmation=%s"; /** * The next action the service implementation should take. */ private Action action; /** * The client ID. */ private long clientId; /** * Resource owner's user account. */ private String subject; /** * Scopes. */ private String[] scopes; /** * Flag to indicate whether the access token exists. */ private boolean existent; /** * Flag to indicate whether the access token is usable * (= exists and has not expired). */ private boolean usable; /** * Flag to indicate whether the access token covers the required scopes. */ private boolean sufficient; /** * Flag to indicate whether the access token is refreshable. */ private boolean refreshable; /** * Entity body of the response to the client. */ private String responseContent; /** * The time at which the access token expires. */ private long expiresAt; /** * Extra properties associated with the access token. */ private Property[] properties; /** * The client ID alias when the authorization request or the token request for * the access token was made. */ private String clientIdAlias; /** * Flag which indicates whether the client ID alias was used when the authorization * request or the token request for the access token was made. */ private boolean clientIdAliasUsed; /** * Confirmation hash for MTLS-bound access tokens. Currently only the S256 * type is supported and is assumed. */ private String certificateThumbprint; /** * The target resources specified by the initial request. */ private URI[] resources; /** * The target resources of the access token. */ private URI[] accessTokenResources; /** * The content of the {@code "authorization_details"} request parameter which was * included in the request that obtained the token. */ private AuthzDetails authorizationDetails; /** * Get the next action the service implementation should take. */ public Action getAction() { return action; } /** * Set the next action the service implementation should take. */ public void setAction(Action action) { this.action = action; } /** * Get the client ID. */ public long getClientId() { return clientId; } /** * Set the client ID. */ public void setClientId(long clientId) { this.clientId = clientId; } /** * Get the subject (= resource owner's ID). * *

* This method returns {@code null} if the access token was generated * by Client Credentials Grant, which means that the access token * is not associated with any specific end-user. *

*/ public String getSubject() { return subject; } /** * Set the subject (= resource owner's ID). */ public void setSubject(String subject) { this.subject = subject; } /** * Get the scopes covered by the access token. */ public String[] getScopes() { return scopes; } /** * Set the scopes covered by the access token. */ public void setScopes(String[] scopes) { this.scopes = scopes; } /** * Get the flag which indicates whether the access token exists. * * @return * {@code true} if the access token exists. * {@code false} if the access token does not exist. */ public boolean isExistent() { return existent; } /** * Set the flag which indicates whether the access token exists. */ public void setExistent(boolean existent) { this.existent = existent; } /** * Get the flag which indicates whether the access token is usable * (= exists and has not expired). * * @return * {@code true} if the access token is usable. {@code false} * if the access token does not exist or has expired. */ public boolean isUsable() { return usable; } /** * Set the flag which indicates whether the access token is usable * (= exists and has not expired). */ public void setUsable(boolean usable) { this.usable = usable; } /** * Get the flag which indicates whether the access token covers * the required scopes. * * @return * {@code true} if the access token covers all the required * scopes. {@code false} if any one of the required scopes * is not covered by the access token. */ public boolean isSufficient() { return sufficient; } /** * Set the flag which indicates whether the access token covers * the required scopes. */ public void setSufficient(boolean sufficient) { this.sufficient = sufficient; } /** * Get the flag which indicates whether the access token can be * refreshed using the associated refresh token. * * @return * {@code true} if the access token can be refreshed using * the associated refresh token. {@code false} if the refresh * token for the access token has expired or the access token * has no associated refresh token. */ public boolean isRefreshable() { return refreshable; } /** * Set the flag which indicates whether the access token can be * refreshed using the associated refresh token. */ public void setRefreshable(boolean refreshable) { this.refreshable = refreshable; } /** * Get the response content which can be used as a part of the * response to the client application. */ public String getResponseContent() { return responseContent; } /** * Set the response content which can be used as a part of the * response to the client application. */ public void setResponseContent(String responseContent) { this.responseContent = responseContent; } /** * Get the time at which the access token expires in milliseconds * since the Unix epoch (1970-01-01). * * @return * The time at which the access token expires. */ public long getExpiresAt() { return expiresAt; } /** * Set the time at which the access token expires in milliseconds * since the Unix epoch (1970-01-01). * * @param expiresAt * The time at which the access token expires. */ public void setExpiresAt(long expiresAt) { this.expiresAt = expiresAt; } /** * Get the extra properties associated with the access token. * * @return * Extra properties. This method returns {@code null} when * no extra property is associated with the access token. * * @since 1.30 */ public Property[] getProperties() { return properties; } /** * Set the extra properties associated with the access token. * * @param properties * Extra properties. * * @since 1.30 */ public void setProperties(Property[] properties) { this.properties = properties; } /** * Get the summary of this instance. */ public String summarize() { return String.format(SUMMARY_FORMAT, action, clientId, subject, existent, usable, sufficient, refreshable, expiresAt, Utils.join(scopes, " "), Utils.stringifyProperties(properties), clientIdAlias, clientIdAliasUsed, certificateThumbprint); } /** * Get the client ID alias when the authorization request or the token * request for the access token was made. Note that this value may be * different from the current client ID alias. * * @return * The client ID alias when the authorization request or the * token request for the access token was made. * * @since 2.3 */ public String getClientIdAlias() { return clientIdAlias; } /** * Set the client ID alias when the authorization request or the token * request for the access token was made. * * @param alias * The client ID alias. * * @since 2.3 */ public void setClientIdAlias(String alias) { this.clientIdAlias = alias; } /** * Get the flag which indicates whether the client ID alias was used * when the authorization request or the token request for the access * token was made. * * @return * {@code true} if the client ID alias was used when the * authorization request or the token request for the access * token was made. * * @since 2.3 */ public boolean isClientIdAliasUsed() { return clientIdAliasUsed; } /** * Set the flag which indicates whether the client ID alias was used * when the authorization request or the token request for the access * token was made. * * @param used * {@code true} if the client ID alias was used when the * authorization request or the token request for the access * token was made. * * @since 2.3 */ public void setClientIdAliasUsed(boolean used) { this.clientIdAliasUsed = used; } /** * Get the client certificate thumbprint used to validate the access token. * * @return * The certificate thumbprint, calculated as the SHA256 hash * of the DER-encoded certificate value. * * @since 2.14 */ public String getCertificateThumbprint() { return certificateThumbprint; } /** * Set the client certificate thumbprint used to validate the access token. * * @param thumbprint * The certificate thumbprint, calculated as the SHA256 hash * of the DER-encoded certificate value. * * @since 2.14 */ public void setCertificateThumbprint(String thumbprint) { this.certificateThumbprint = thumbprint; } /** * Get the target resources. This represents the resources specified by * the {@code resource} request parameters or by the {@code resource} * property in the request object. * *

* See "Resource Indicators for OAuth 2.0" for details. *

* * @return * Target resources. * * @see #getAccessTokenResources() * * @since 2.62 */ public URI[] getResources() { return resources; } /** * Set the target resources. This represents the resources specified by * the {@code resource} request parameters or by the {@code resource} * property in the request object. * * @param resources * Target resources. * * @see #setAccessTokenResources(URI[]) * * @since 2.62 */ public void setResources(URI[] resources) { this.resources = resources; } /** * Get the target resources of the access token. * *

* The target resources returned by this method may be the same as or * different from the ones returned by {@link #getResources()}. *

* *

* In some flows, the initial request and the subsequent token request * are sent to different endpoints. Example flows are the Authorization * Code Flow, the Refresh Token Flow, the CIBA Ping Mode, the CIBA Poll * Mode and the Device Flow. In these flows, not only the initial request * but also the subsequent token request can include the {@code resource} * request parameters. The purpose of the {@code resource} request * parameters in the token request is to narrow the range of the target * resources from the original set of target resources requested by the * preceding initial request. If narrowing down is performed, the target * resources returned by {@link #getResources()} and the ones returned by * this method are different. This method returns the narrowed set of * target resources. *

* *

* See "Resource Indicators for OAuth 2.0" for details. *

* * @return * The target resources of the access token. * * @see #getResources() * * @since 2.62 */ public URI[] getAccessTokenResources() { return accessTokenResources; } /** * Set the target resources of the access token. * *

* See the description of {@link #getAccessTokenResources()} for details * about the target resources of the access token. *

* * @param resources * The target resources of the access token. * * @see #setResources(URI[]) * * @since 2.62 */ public void setAccessTokenResources(URI[] resources) { this.accessTokenResources = resources; } /** * Get the authorization details. This represents the value of the * {@code "authorization_details"} request parameter which is defined in * "OAuth 2.0 Rich Authorization Requests". * * @return * Authorization details. * * @since 2.56 */ public AuthzDetails getAuthorizationDetails() { return authorizationDetails; } /** * Set the authorization details. This represents the value of the * {@code "authorization_details"} request parameter which is defined in * "OAuth 2.0 Rich Authorization Requests". * * @param details * Authorization details. * * @since 2.56 */ public void setAuthorizationDetails(AuthzDetails details) { this.authorizationDetails = details; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy