
com.authlete.jaxrs.spi.AuthorizationDecisionHandlerSpi Maven / Gradle / Ivy
Show all versions of authlete-java-jaxrs Show documentation
/*
* Copyright (C) 2016-2022 Authlete, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package com.authlete.jaxrs.spi;
import java.util.List;
import com.authlete.common.assurance.VerifiedClaims;
import com.authlete.common.assurance.constraint.VerifiedClaimsConstraint;
import com.authlete.common.dto.Property;
/**
* Service Provider Interface to work with {@link
* com.authlete.jaxrs.AuthorizationDecisionHandler AuthorizationDecisionHandler}.
*
*
* An implementation of this interface must be given to the constructor
* of {@link com.authlete.jaxrs.AuthorizationDecisionHandler
* AuthorizationDecisionHandler} class.
*
*
* @author Takahiko Kawasaki
*/
public interface AuthorizationDecisionHandlerSpi
{
/**
* Get the decision on the authorization request.
*
* @return
* {@code true} if the end-user has decided to grant
* authorization to the client application. Otherwise,
* {@code false}.
*/
boolean isClientAuthorized();
/**
* Get the time when the end-user was authenticated.
*
*
* For example, if an authorization always requires an end-user
* to login, the authentication time is always "just now", so
* the implementation of this method will be like the following.
*
*
*
*
* @Override
* public long getUserAuthenticatedAt()
* {
* return System.currentTimeMillis() / 1000;
* }
*
*
*
* This method is not called when {@link #isClientAuthorized()}
* has returned {@code false}.
*
*
* @return
* The time when the end-user authentication occurred.
* The number of seconds since Unix epoch (1970-01-01).
* Return 0 if the time is unknown.
*/
long getUserAuthenticatedAt();
/**
* Get the subject (= unique identifier) of the end-user.
* It must consist of only ASCII letters and its length
* must not exceed 100.
*
*
* In a typical case, the subject is a primary key or another
* unique ID of the record that represents the end-user in
* your user database.
*
*
*
* This method is not called when {@link #isClientAuthorized()}
* has returned {@code false}.
*
*
* @return
* The subject (= unique identifier) of the end-user.
* Returning {@code null} makes the authorization
* request fail.
*/
String getUserSubject();
/**
* Get the authentication context class reference (ACR) that was
* satisfied when the current end-user was authenticated.
*
*
* The value returned by this method has an important meaning only
* when an authorization requests {@code acr} claim as an essential
* claim. Practically speaking, it is unlikely to happen. See "5.5.1.1. Requesting the "acr" Claim" in OpenID
* Connect Core 1.0 if you are interested in the details.
*
*
*
* If you don't know what ACR is, return {@code null}.
*
*
* @return
* The authentication context class reference (ACR) that
* was satisfied when the current end-user was authenticated.
*/
String getAcr();
/**
* Get the value of a claim of the user.
*
*
* This method may be called multiple times. On the other hand,
* this method is not called when {@link #isClientAuthorized()}
* has returned {@code false} or when {@link #getUserSubject()}
* has returned {@code null}.
*
*
*
* If the claim name starts with two colons ({@code ::}), the claim is a
* predefined transformed claim. The value of the claim will be
* computed by Authlete, so the exact value returned by this method is
* not so important. If this method returns a non-null value, the value
* of the transformed claim will be computed by Authlete and embedded in
* the ID token.
*
*
*
* Likewise, if the claim name starts with one colon ({@code :}), the claim
* is a transformed claim defined in the {@code "transformed_claims"}
* property in the {@code claims} request parameter. If this method returns
* a non-null value, the value of the transformed claim will be computed by
* Authlete and embedded in the ID token.
*
*
*
* See OpenID Connect Advanced Syntax for Claims (ASC) 1.0 for details
* about transformed claims.
*
*
* @param claimName
* A claim name such as {@code name} and {@code family_name}.
* Standard claim names are listed in "5.1. Standard Claims" of OpenID
* Connect Core 1.0. Java constant values that represent the
* standard claims are listed in {@link com.authlete.common.types.StandardClaims
* StandardClaims} class. The value of {@code claimName} does NOT
* contain a language tag.
*
* @param languageTag
* A language tag such as {@code en} and {@code ja}. Implementations
* should take this into account whenever possible. See "5.2. Claims Languages and Scripts" in OpenID
* Connect Core 1.0 for details.
*
* @return
* The claim value. {@code null} if the claim value of the claim
* is not available.
*/
Object getUserClaim(String claimName, String languageTag);
/**
* Get extra properties to associate with an access token and/or an
* authorization code.
*
*
* This method is expected to return an array of extra properties.
* The following is an example that returns an array containing one
* extra property.
*
*
*
* @Override
* public {@link Property}[] getProperties()
* {
* return new {@link Property}[] {
* new {@link Property#Property(String, String)
* Property}("example_parameter", "example_value")
* };
* }
*
*
*
* Extra properties returned from this method will appear as top-level entries
* in a JSON response from an authorization server as shown in 5.1. Successful Response
* in RFC 6749.
*
*
*
* Keys listed below should not be used and they would be ignored on
* the server side even if they were used. It's because they are reserved
* in RFC 6749 and
* OpenID Connect Core 1.0.
*
*
*
* - {@code access_token}
*
- {@code token_type}
*
- {@code expires_in}
*
- {@code refresh_token}
*
- {@code scope}
*
- {@code error}
*
- {@code error_description}
*
- {@code error_uri}
*
- {@code id_token}
*
*
*
* Note that there is an upper limit on the total size of extra properties.
* On the server side, the properties will be (1) converted to a multidimensional
* string array, (2) converted to JSON, (3) encrypted by AES/CBC/PKCS5Padding, (4)
* encoded by base64url, and then stored into the database. The length of the
* resultant string must not exceed 65,535 in bytes. This is the upper limit, but
* we think it is big enough.
*
*
* @return
* Extra properties. If {@code null} is returned, any extra property will
* not be associated.
*
* @since 1.3
*/
Property[] getProperties();
/**
* Get scopes to associate with an access token and/or an authorization code.
*
*
* If {@code null} is returned, the scopes specified in the original
* authorization request from the client application are used. In other
* cases, including the case of an empty array, the specified scopes will
* replace the original scopes contained in the original authorization
* request.
*
*
*
* Even scopes that are not included in the original authorization request
* can be specified. However, as an exception, "openid"
scope
* is ignored on the server side if it is not included in the original
* request. It is because the existence of "openid"
scope
* considerably changes the validation steps and because adding
* "openid"
triggers generation of an ID token (although the
* client application has not requested it) and the behavior is a major
* violation against the specification.
*
*
*
* If you add "offline_access"
scope although it is not
* included in the original request, keep in mind that the specification
* requires explicit consent from the user for the scope (OpenID Connect Core 1.0, 11. Offline Access). When
* "offline_access"
is included in the original request, the
* current implementation of Authlete's /api/auth/authorization API checks
* whether the request has come along with prompt
request
* parameter and the value includes "consent"
. However, note
* that the implementation of Authlete's /api/auth/authorization/issue API
* does not perform such checking if "offline_access"
scope
* is added via this scopes
parameter.
*
*
* @return
* Scopes to associate with an authorization code and/or an access
* token. If a non-null value is set, the original scopes requested
* by the client application are replaced.
*
* @since 1.4
*/
String[] getScopes();
/**
* Get the value of the "sub" claim to be used in the id_token.
*
*
* If doing a pairwise subject derivation, this method should check the
* registration of the current Client to see if it has a PAIRWISE subject
* identifier type. If so, it returns the calculated string of that subject.
* If not, it returns {@code null} and the value of {@link #getUserSubject()}
* is used by the API instead.
*
*
* @return
* The value of the "sub" claim to be used in the id_token,
* or {@code null} if no such subject exists.
*
* @since 2.22
*/
String getSub();
/**
* Get the verified claims of the user to be embedded in the ID token.
*
*
* NOTE: Since version 2.42, this method is called only when the
* {@link com.authlete.jaxrs.AuthorizationDecisionHandler.Params#isOldIdaFormatUsed()
* isOldIdaFormatUsed()} method of
* {@link com.authlete.jaxrs.AuthorizationDecisionHandler.Params
* AuthorizationDecisionHandler.Params} returns true. See the description
* of the method for details.
*
*
*
* An authorization request may contain a {@code "claims"} request parameter.
* The value of the request parameter is JSON which conforms to the format
* defined in 5.5. Requesting Claims using the "claims" Request Parameter of
* OpenID
* Connect Core 1.0. The JSON may contain an {@code "id_token"} property.
* The value of the property is a JSON object which lists claims that the
* client application wants to be embedded in the ID token. The following
* is an example shown in the section.
*
*
*
* {
* "userinfo":
* {
* "given_name": {"essential": true},
* "nickname": null,
* "email": {"essential": true},
* "email_verified": {"essential": true},
* "picture": null,
* "http://example.info/claims/groups": null
* },
* "id_token":
* {
* "auth_time": {"essential": true},
* "acr": {"values": ["urn:mace:incommon:iap:silver"] }
* }
* }
*
*
*
* OpenID Connect for Identity Assurance 1.0 has extended this mechanism
* to allow client applications to request verified claims. To request
* verified claims, a {@code "verified_claims"} property is included in the
* {@code "id_token"} property like below.
*
*
*
* {
* "id_token": {
* "verified_claims": {
* "verification": {
* "trust_framework": {
* "value": "de_aml"
* },
* "evidence": [
* {
* "type": {
* "value": "id_document"
* },
* "method": {
* "value": "pipp"
* },
* "document": {
* "type": {
* "values": [
* "idcard",
* "passport"
* ]
* }
* }
* }
* ]
* },
* "claims": {
* "given_name": null,
* "family_name": {
* "essential": true
* },
* "birthdate": {
* "purpose": "To send you best wishes on your birthday"
* }
* }
* }
* }
* }
*
*
*
* This method should return the requested verified claims.
*
*
* @param subject
* The subject of the user. The same value returned by
* {@link #getUserSubject()}.
*
* @param constraint
* An object that represents the {@code "verified_claims"} in the
* {@code "id_token"} property.
*
* @return
* The verified claims. The returned value is embedded in the ID
* token as the value of the {@code "verified_claims"} claim.
* If this method returns null, the {@code "verified_claims"} claim
* does not appear in the ID token.
*
* @since 2.25
*
* @see #getVerifiedClaims(String, Object)
*
* @deprecated
*/
@Deprecated
List getVerifiedClaims(String subject, VerifiedClaimsConstraint constraint);
/**
* Get the verified claims of the user to be embedded in the ID token.
*
*
* An authorization request may contain a {@code "claims"} request parameter.
* The value of the request parameter is JSON which conforms to the format
* defined in 5.5. Requesting Claims using the "claims" Request Parameter of
* OpenID
* Connect Core 1.0. The JSON may contain an {@code "id_token"} property.
* The value of the property is a JSON object which lists claims that the
* client application wants to be embedded in the ID token. The following
* is an example shown in the section.
*
*
*
* {
* "userinfo":
* {
* "given_name": {"essential": true},
* "nickname": null,
* "email": {"essential": true},
* "email_verified": {"essential": true},
* "picture": null,
* "http://example.info/claims/groups": null
* },
* "id_token":
* {
* "auth_time": {"essential": true},
* "acr": {"values": ["urn:mace:incommon:iap:silver"] }
* }
* }
*
*
*
* OpenID Connect for Identity Assurance 1.0 has extended this mechanism
* to allow client applications to request verified claims. To request
* verified claims, a {@code "verified_claims"} property is included in the
* {@code "id_token"} property like below.
*
*
*
* {
* "id_token": {
* "verified_claims": {
* "verification": {
* "trust_framework": null,
* "time": null,
* "evidence": [
* {
* "type": {
* "value": "document"
* },
* "method": null,
* "document_details": {
* "type": null
* }
* }
* ]
* },
* "claims": {
* "given_name": null,
* "family_name": null,
* "birthdate": null
* }
* }
* }
* }
*
*
*
* The second argument ({@code verifiedClaimsRequest}) of this method
* represents the value of {@code "verified_claims"} in the request.
* It is a {@code Map} instance or a {@code List} instance. The latter
* case happens when the value of {@code "verified_claims"} is a JSON
* array like below.
*
*
*
* {
* "id_token": {
* "verified_claims": [
* {
* "verification": {
* "trust_framework": {
* "value": "gold"
* },
* "evidence": [
* {
* "type": {
* "value": "document"
* }
* }
* ]
* },
* "claims": {
* "given_name": null,
* "family_name": null
* }
* },
* {
* "verification": {
* "trust_framework": {
* "values": [
* "silver",
* "bronze"
* ]
* },
* "evidence": [
* {
* "type": {
* "value": "vouch"
* }
* }
* ]
* },
* "claims": {
* "given_name": null,
* "family_name": null
* }
* }
* ]
* }
* }
*
*
*
* When the given argument is a {@code Map} instance, it can be cast by
* {@code Map}. On the other hand, in the case of a
* {@code List} instance, each element in the list can be cast by
* {@code Map}.
*
*
*
* This method should return a {@code Map} instance or a {@code List}
* instance which represents the value of {@code "verified_claims"}. The
* value will be embedded in the ID token as the value of
* {@code "verified_claims"}.
*
*
*
* For example, to make an ID token include {@code "verified_claims"} like
* below,
*
*
*
* "verified_claims": {
* "verification": {
* "trust_framework": "trust_framework_example"
* },
* "claims": {
* "given_name": "Max",
* "family_name": "Meier"
* }
* }
*
*
* this method should build a {@code Map} instance like below and return it.
*
*
* Map<String, Object> verification = new HashMap<>();
* verification.put("trust_framework", "trust_framework_example");
*
* Map<String, Object> claims = new HashMap<>();
* claims.put("given_name", "Max");
* claims.put("family_name", "Meier");
*
* Map<String, Object> verified_claims = new HashMap<>();
* verified_claims.put("verification", verification);
* verified_claims.put("claims", claims);
*
* return verified_claims;
*
*
* @param subject
* The subject of the user. The same value returned by
* {@link #getUserSubject()}.
*
* @param verifiedClaimsRequest
* An object that represents the {@code "verified_claims"} in the
* {@code "id_token"} property in the {@code "claims"} request
* parameter. Either a {@code Map} instance or a {@code List}
* instance.
*
* @return
* The verified claims. The returned value is embedded in the ID
* token as the value of {@code "verified_claims"}. If this method
* returns null, {@code "verified_claims"} does not appear in the
* ID token.
*
* @since 2.42
*
* @see OpenID Connect for Identity Assurance 1.0
*/
Object getVerifiedClaims(String subject, Object verifiedClaimsRequest);
}