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

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

/*
 * Copyright (C) 2015-2018 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 com.authlete.common.util.Utils;



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

* Authlete's {@code /auth/userinfo} 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 the UserInfo * Endpoint implementation of your service can use the string returned * from the method as the value of {@code WWW-Authenticate} header. *

* *

* The following is an example response which complies with RFC 6750. * Note that OpenID Connect Core 1.0 requires that an error response from * UserInfo endpoint comply with RFC 6750. See 5.3.3. UserInfo Error Response for details. *

* *
 * 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 the UserInfo * Endpoint implementation of your service can use the string returned * from the method as the value of {@code WWW-Authenticate} header. *

* *

* The following is an example response which complies with RFC 6750. * Note that OpenID Connect Core 1.0 requires that an error response from * UserInfo endpoint comply with RFC 6750. See 5.3.3. UserInfo Error Response for details. *

* *
 * 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, has expired, or is not associated * with any subject (= any user account). *

* *

* {@link #getResponseContent()} returns a string which describes the error * in the format of RFC 6750 * (OAuth 2.0 Bearer Token Usage), so the UserInfo * Endpoint implementation of your service can use the string returned * from the method as the value of {@code WWW-Authenticate} header. *

* *

* The following is an example response which complies with RFC 6750. * Note that OpenID Connect Core 1.0 requires that an error response from * UserInfo endpoint comply with RFC 6750. See 5.3.3. UserInfo Error Response for details. *

* *
 * 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 include the {@code "openid"} scope. *

* *

* {@link #getResponseContent()} returns a string which describes the error * in the format of RFC 6750 * (OAuth 2.0 Bearer Token Usage), so the UserInfo * Endpoint implementation of your service can use the string returned * from the method as the value of {@code WWW-Authenticate} header. *

* *

* The following is an example response which complies with RFC 6750. * Note that OpenID Connect Core 1.0 requires that an error response from * UserInfo endpoint comply with RFC 6750. See 5.3.3. UserInfo Error Response for details. *

* *
 * 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. To be * concrete, it means that the access token exists, has not expired, * includes the {@code "openid"} scope, and is associated with a subject * (= a user account). *

* *

* What the UserInfo * Endpoint of your service should do next is to collect information * about the subject (user) from your database. The value of the subject * can be obtained from {@link #getSubject()}, and the names of data, i.e., * the claims names can be obtained from {@link #getClaims()}. * For example, if {@code getSubject()} returns {@code "joe123"} and {@code * getClaims()} returns {@code ["given_name", "email"]}, you need to extract * information about {@code joe123}'s given name and email from your * database. *

* *

* Then, call Authlete's {@code /auth/userinfo/issue} API with the collected * information and the access token in order to make Authlete generate a userinfo * response. See the descriptions of {@link com.authlete.common.dto.UserInfoIssueRequest * UserInfoIssueRequest} and {@link com.authlete.common.dto.UserInfoIssueResponse * UserInfoIssueResponse} for details about {@code /auth/userinfo/issue} API. *

* *

* If an error occurred during the above steps, generate an error response * to the client. The response should comply with RFC 6750. For example, * if the subject associated with the access token does not exist in your * database any longer, you may feel like generating a response like below. *

* *
 * HTTP/1.1 400 Bad Request
 * WWW-Authenticate: Bearer error="{@link com.authlete.common.types.ErrorCode#invalid_token
 * invalid_token}",
 *  error_description="The subject associated with the access token does not exist."
 * Cache-Control: no-store
 * Pragma: no-cache
* *

* Also, an error might occur on database access. If you treat the error * as an internal server error, then the response would be like the following. *

* *
 * HTTP/1.1 500 Internal Server Error
 * WWW-Authenticate: Bearer error="{@link com.authlete.common.types.ErrorCode#server_error
 * server_error}",
 *  error_description="Failed to extract information about the subject from the database."
 * Cache-Control: no-store
 * Pragma: no-cache
* *
*
* * @author Takahiko Kawasaki */ public class UserInfoResponse extends ApiResponse { private static final long serialVersionUID = 2L; /** * 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. To be * concrete, the access token does not include the {@code * "openid"} scope. The service implementation should return * {@code "403 Forbidden"} to the client application. */ FORBIDDEN, /** * The access token is valid. The service implementation should * collect information about requested claims and pass the * information to Authlete's {@code /auth/userinfo/issue} * endpoint in order to make Authlete generate an ID token. */ OK } private static final String SUMMARY_FORMAT = "action=%s, clientId=%d, subject=%s, scopes=%s, claims=%s, " + "accessToken=%s, properties=%s, clientIdAlias=%s, clientIdAliasUsed=%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; /** * Claims that are requested by the client application. */ private String[] claims; /** * The access token that came along with the userinfo request. */ private String token; /** * Entity body of the response to the client. */ private String responseContent; /** * Extra properties associated with the access token. */ private Property[] properties; /** * The client ID alias when the authorization request for * the access token was made. */ private String clientIdAlias; /** * Flag which indicates whether the client ID alias was used * when the authorization request for the access token was made. */ private boolean clientIdAliasUsed; /** * 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). */ 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 list of claims that the client application requests * to be embedded in the userinfo response. The value comes from * {@code "scope"} and {@code "claims"} request parameters of * the original authorization request. * * @see OpenID Connect Core 1.0, 5.4. Requesting Claims using Scope Values * * @see OpenID Connect Core 1.0, 5.5. Requesting Claims using * the "claims" Request Parameter */ public String[] getClaims() { return claims; } /** * Set the list of claims that the client application requests * to be embedded in the ID token. */ public void setClaims(String[] claims) { this.claims = claims; } /** * Get the access token that came along with the userinfo request. */ public String getToken() { return token; } /** * Set the access token that came along with the userinfo request. */ public void setToken(String accessToken) { this.token = accessToken; } /** * 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 summary of this instance. */ public String summarize() { return String.format(SUMMARY_FORMAT, action, clientId, subject, Utils.join(scopes, " "), Utils.join(claims, " "), token, Utils.stringifyProperties(properties), clientIdAlias, clientIdAliasUsed); } /** * 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 2.5 */ public Property[] getProperties() { return properties; } /** * Set the extra properties associated with the access token. * * @param properties * Extra properties. * * @since 2.5 */ public void setProperties(Property[] properties) { this.properties = properties; } /** * Get the client ID alias when the authorization 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 for the * access token was made. * * @since 2.5 */ public String getClientIdAlias() { return clientIdAlias; } /** * Set the client ID alias when the authorization request for the access * token was made. * * @param alias * The client ID alias. * * @since 2.5 */ public void setClientIdAlias(String alias) { this.clientIdAlias = alias; } /** * Get the flag which indicates whether the client ID alias was used * when the authorization request for the access token was made. * * @return * {@code true} if the client ID alias was used when the * authorization request for the access token was made. * * @since 2.5 */ public boolean isClientIdAliasUsed() { return clientIdAliasUsed; } /** * Set the flag which indicates whether the client ID alias was used * when the authorization request for the access token was made. * * @param used * {@code true} if the client ID alias was used when the * authorization request for the access token was made. * * @since 2.5 */ public void setClientIdAliasUsed(boolean used) { this.clientIdAliasUsed = used; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy