001package com.nimbusds.openid.connect.provider.spi.grants; 002 003 004import net.jcip.annotations.ThreadSafe; 005import org.checkerframework.checker.nullness.qual.Nullable; 006 007import com.nimbusds.jose.JOSEObject; 008import com.nimbusds.oauth2.sdk.GeneralException; 009import com.nimbusds.oauth2.sdk.Scope; 010import com.nimbusds.oauth2.sdk.id.ClientID; 011import com.nimbusds.openid.connect.provider.spi.InvocationContext; 012import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata; 013 014 015/** 016 * Service Provider Interface (SPI) for handling JSON Web Token (JWT) assertion 017 * grants issued by a third-party security token service. Returns the matching 018 * {@link ThirdPartyAssertionAuthorization authorisation} on success. Must 019 * throw a {@link GeneralException} with an 020 * {@link com.nimbusds.oauth2.sdk.OAuth2Error#INVALID_GRANT invalid_grant} 021 * error code if the JWT assertion is invalid. 022 * 023 * <p>The passed JWT assertion can be an instance of: 024 * 025 * <ul> 026 * <li>{@link com.nimbusds.jwt.SignedJWT} -- Signed or MAC protected with 027 * JWS; 028 * <li>{@link com.nimbusds.jwt.EncryptedJWT} -- Encrypted with JWE; 029 * <li>{@link com.nimbusds.jose.JWEObject} -- Signed or MAC protected with 030 * JWS, then encrypted with JWE. 031 * </ul> 032 * 033 * <p>The handler should not specify access token lifetimes that exceed the 034 * validity period of the JWT assertion by a significant period. The issue of 035 * refresh tokens is not permitted. Clients can refresh an expired access token 036 * by requesting a new one using the same assertion, if it is still valid, or 037 * with a new assertion. 038 * 039 * <p>Implementations must be thread-safe. 040 * 041 * <p>Related specifications: 042 * 043 * <ul> 044 * <li>Assertion Framework for OAuth 2.0 Client Authentication and 045 * Authorization Grants (RFC 7521), section 4.1. 046 * <li>JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and 047 * Authorization Grants (RFC 7523), sections 2.1, 3 and 3.1. 048 * </ul> 049 */ 050@ThreadSafe 051public interface ThirdPartyJWTGrantHandler extends JWTGrantHandler { 052 053 054 /** 055 * Handles a JWT bearer assertion grant issued by a third-party 056 * security token service (STS). The grant handler must verify the JWT 057 * assertion, using a previously agreed method to resolve the client's 058 * MAC or signature key. 059 * 060 * <p>The following client authentication / identification cases may be 061 * handled: 062 * 063 * <ol> 064 * <li><strong>Confidential client: </strong> 065 * If the client is confidential and has provided valid 066 * authentication (client_secret_basic, client_secret_post, 067 * client_secret_jwt or private_key_jwt) the 068 * {@code confidentialClient} flag will be {@code true}. The 069 * client_id and metadata arguments will be set. 070 * <li><strong>Public client: </strong> 071 * If the client is public and has a provided its registered 072 * {@code client_id} using the optional token request 073 * parameter, the {@code confidentialClient} flag will be 074 * {@code false} and the client metadata will be set. 075 * <li><strong>Handler must resolve client_id from JWT claims: </strong> 076 * If no client authentication or {@code client_id} is passed 077 * with the token request, the client information arguments 078 * will be {@code null} and the {@code confidentialClient} flag 079 * will be {@code false}. The grant handler must resolve the 080 * {@code client_id} for the authorisation result from claims 081 * of the JWT assertion. If such a use case is not supported or 082 * permitted the grant handler should throw a 083 * {@link GeneralException} with an 084 * {@link com.nimbusds.oauth2.sdk.OAuth2Error#INVALID_REQUEST 085 * invalid_request} error. 086 * </ol> 087 * 088 * <p>If the JWT assertion is invalid the handler must throw a 089 * {@link GeneralException} with an 090 * {@link com.nimbusds.oauth2.sdk.OAuth2Error#INVALID_GRANT 091 * invalid_grant} error code. 092 * 093 * <p>If the requested scope is invalid, unknown, malformed, or exceeds 094 * the scope granted by the resource owner the handler must throw a 095 * {@link GeneralException} with an 096 * {@link com.nimbusds.oauth2.sdk.OAuth2Error#INVALID_SCOPE 097 * invalid_scope} error code. 098 * 099 * @param jwtAssertion The JWT assertion, to be verified / 100 * decrypted by the handler. Can be a signed 101 * JWT, an encrypted JWT, or a signed and 102 * encrypted (nested) JWT. Not {@code null}. 103 * @param scope The requested scope, {@code null} if not 104 * specified. 105 * @param clientID The client identifier, {@code null} if not 106 * specified or if no client authentication 107 * was provided. 108 * @param confidentialClient {@code true} if the client is confidential 109 * and has been authenticated, else 110 * {@code false}. 111 * @param clientMetadata The OAuth 2.0 / OpenID Connect client 112 * metadata, {@code null} if no 113 * {@code client_id} or client authentication 114 * was provided. 115 * 116 * @return The authorisation. 117 * 118 * @throws GeneralException If the grant is invalid, or another 119 * exception was encountered. 120 */ 121 @Deprecated 122 default ThirdPartyAssertionAuthorization processThirdPartyGrant(final JOSEObject jwtAssertion, 123 final @Nullable Scope scope, 124 final @Nullable ClientID clientID, 125 final boolean confidentialClient, 126 final @Nullable OIDCClientMetadata clientMetadata) 127 throws GeneralException { 128 129 return null; 130 } 131 132 133 /** 134 * Handles a JWT bearer assertion grant issued by a third-party 135 * security token service (STS). The grant handler must verify the JWT 136 * assertion, using a previously agreed method to resolve the client's 137 * MAC or signature key. 138 * 139 * <p>The following client authentication / identification cases may be 140 * handled: 141 * 142 * <ol> 143 * <li><strong>Confidential client: </strong> 144 * If the client is confidential and has provided valid 145 * authentication (client_secret_basic, client_secret_post, 146 * client_secret_jwt or private_key_jwt) the 147 * {@code confidentialClient} flag will be {@code true}. The 148 * client_id and metadata arguments will be set. 149 * <li><strong>Public client: </strong> 150 * If the client is public and has a provided its registered 151 * {@code client_id} using the optional token request 152 * parameter, the {@code confidentialClient} flag will be 153 * {@code false} and the client metadata will be set. 154 * <li><strong>Handler must resolve client_id from JWT claims: </strong> 155 * If no client authentication or {@code client_id} is passed 156 * with the token request, the client information arguments 157 * will be {@code null} and the {@code confidentialClient} flag 158 * will be {@code false}. The grant handler must resolve the 159 * {@code client_id} for the authorisation result from claims 160 * of the JWT assertion. If such a use case is not supported or 161 * permitted the grant handler should throw a 162 * {@link GeneralException} with an 163 * {@link com.nimbusds.oauth2.sdk.OAuth2Error#INVALID_REQUEST 164 * invalid_request} error. 165 * </ol> 166 * 167 * <p>If the JWT assertion is invalid the handler must throw a 168 * {@link GeneralException} with an 169 * {@link com.nimbusds.oauth2.sdk.OAuth2Error#INVALID_GRANT 170 * invalid_grant} error code. 171 * 172 * <p>If the requested scope is invalid, unknown, malformed, or exceeds 173 * the scope granted by the resource owner the handler must throw a 174 * {@link GeneralException} with an 175 * {@link com.nimbusds.oauth2.sdk.OAuth2Error#INVALID_SCOPE 176 * invalid_scope} error code. 177 * 178 * @param jwtAssertion The JWT assertion, to be verified / 179 * decrypted by the handler. Can be a signed 180 * JWT, an encrypted JWT, or a signed and 181 * encrypted (nested) JWT. Not {@code null}. 182 * @param tokenRequestParams The token request parameters, such as the 183 * requested scope. Not {@code null}. 184 * @param clientID The client identifier, {@code null} if not 185 * specified or if no client authentication 186 * was provided. 187 * @param confidentialClient {@code true} if the client is confidential 188 * and has been authenticated, else 189 * {@code false}. 190 * @param clientMetadata The OAuth 2.0 / OpenID Connect client 191 * metadata, {@code null} if no 192 * {@code client_id} or client authentication 193 * was provided. 194 * @param invocationCtx The invocation context. Not {@code null}. 195 * 196 * @return The authorisation. 197 * 198 * @throws GeneralException If the grant is invalid, or another 199 * exception was encountered. 200 */ 201 default ThirdPartyAssertionAuthorization processThirdPartyGrant(final JOSEObject jwtAssertion, 202 final TokenRequestParameters tokenRequestParams, 203 final @Nullable ClientID clientID, 204 final boolean confidentialClient, 205 final @Nullable OIDCClientMetadata clientMetadata, 206 final InvocationContext invocationCtx) 207 throws GeneralException { 208 209 return processThirdPartyGrant(jwtAssertion, tokenRequestParams.getScope(), clientID, confidentialClient, clientMetadata); 210 } 211}