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