協議端點

OAuth2 授權端點

OAuth2AuthorizationEndpointConfigurer 提供了自定義 OAuth2 授權端點 的能力。它定義了擴充套件點,允許您自定義 OAuth2 授權請求 的預處理、主處理和後處理邏輯。

OAuth2AuthorizationEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
				.authorizationEndpoint(authorizationEndpoint ->
					authorizationEndpoint
        				.authorizationRequestConverter(authorizationRequestConverter)   (1)
                        .authorizationRequestConverters(authorizationRequestConvertersConsumer) (2)
                        .authenticationProvider(authenticationProvider) (3)
                        .authenticationProviders(authenticationProvidersConsumer)   (4)
                        .authorizationResponseHandler(authorizationResponseHandler) (5)
                        .errorResponseHandler(errorResponseHandler) (6)
                        .consentPage("/oauth2/v1/authorize")    (7)
				)
		);

	return http.build();
}
1 authorizationRequestConverter():新增一個 AuthenticationConverter (預處理器),用於嘗試將 OAuth2 授權請求 (或同意) 從 HttpServletRequest 提取到 OAuth2AuthorizationCodeRequestAuthenticationTokenOAuth2AuthorizationConsentAuthenticationToken 例項。
2 authorizationRequestConverters():設定 Consumer,提供對預設和(可選)新增的 AuthenticationConverter 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationConverter
3 authenticationProvider():新增一個 AuthenticationProvider (主處理器),用於驗證 OAuth2AuthorizationCodeRequestAuthenticationTokenOAuth2AuthorizationConsentAuthenticationToken
4 authenticationProviders():設定 Consumer,提供對預設和(可選)新增的 AuthenticationProvider 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationProvider
5 authorizationResponseHandler()AuthenticationSuccessHandler (後處理器),用於處理“已認證”的 OAuth2AuthorizationCodeRequestAuthenticationToken 並返回 OAuth2AuthorizationResponse
6 errorResponseHandler()AuthenticationFailureHandler (後處理器),用於處理 OAuth2AuthorizationCodeRequestAuthenticationException 並返回 OAuth2Error 響應
7 consentPage():自定義同意頁面的 URI,如果授權請求流程中需要同意,則重定向資源所有者到該頁面。

OAuth2AuthorizationEndpointConfigurer 配置 OAuth2AuthorizationEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @BeanOAuth2AuthorizationEndpointFilter 是處理 OAuth2 授權請求(和同意)的 Filter

OAuth2AuthorizationEndpointFilter 配置了以下預設值

  • AuthenticationConverter — 由 OAuth2AuthorizationCodeRequestAuthenticationConverterOAuth2AuthorizationConsentAuthenticationConverter 組成的 DelegatingAuthenticationConverter

  • AuthenticationManager — 由 OAuth2AuthorizationCodeRequestAuthenticationProviderOAuth2AuthorizationConsentAuthenticationProvider 組成的 AuthenticationManager

  • AuthenticationSuccessHandler — 一個內部實現,用於處理“已認證”的 OAuth2AuthorizationCodeRequestAuthenticationToken 並返回 OAuth2AuthorizationResponse

  • AuthenticationFailureHandler — 一個內部實現,它使用與 OAuth2AuthorizationCodeRequestAuthenticationException 關聯的 OAuth2Error 並返回 OAuth2Error 響應。

自定義授權請求驗證

OAuth2AuthorizationCodeRequestAuthenticationValidator 是用於驗證授權碼授權中特定 OAuth2 授權請求引數的預設驗證器。預設實現驗證 redirect_uriscope 引數。如果驗證失敗,將丟擲 OAuth2AuthorizationCodeRequestAuthenticationException

OAuth2AuthorizationCodeRequestAuthenticationProvider 透過向 setAuthenticationValidator() 提供型別為 Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> 的自定義身份驗證驗證器,提供了覆蓋預設授權請求驗證的能力。

OAuth2AuthorizationCodeRequestAuthenticationContext 包含 OAuth2AuthorizationCodeRequestAuthenticationToken,其中包含 OAuth2 授權請求引數。
如果驗證失敗,身份驗證驗證器 必須 丟擲 OAuth2AuthorizationCodeRequestAuthenticationException

在開發生命週期階段,一個常見的用例是允許 redirect_uri 引數中的 localhost

以下示例展示瞭如何使用自定義身份驗證驗證器配置 OAuth2AuthorizationCodeRequestAuthenticationProvider,該驗證器允許 redirect_uri 引數中的 localhost

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
				.authorizationEndpoint(authorizationEndpoint ->
					authorizationEndpoint
                        .authenticationProviders(configureAuthenticationValidator())
				)
		);

	return http.build();
}

private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
	return (authenticationProviders) ->
		authenticationProviders.forEach((authenticationProvider) -> {
			if (authenticationProvider instanceof OAuth2AuthorizationCodeRequestAuthenticationProvider) {
				Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> authenticationValidator =
					// Override default redirect_uri validator
					new CustomRedirectUriValidator()
						// Reuse default scope validator
						.andThen(OAuth2AuthorizationCodeRequestAuthenticationValidator.DEFAULT_SCOPE_VALIDATOR);

				((OAuth2AuthorizationCodeRequestAuthenticationProvider) authenticationProvider)
					.setAuthenticationValidator(authenticationValidator);
			}
		});
}

static class CustomRedirectUriValidator implements Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> {

	@Override
	public void accept(OAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext) {
		OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication =
			authenticationContext.getAuthentication();
		RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
		String requestedRedirectUri = authorizationCodeRequestAuthentication.getRedirectUri();

		// Use exact string matching when comparing client redirect URIs against pre-registered URIs
		if (!registeredClient.getRedirectUris().contains(requestedRedirectUri)) {
			OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST);
			throw new OAuth2AuthorizationCodeRequestAuthenticationException(error, null);
		}
	}
}

OAuth2 推送授權請求端點

OAuth2PushedAuthorizationRequestEndpointConfigurer 提供了自定義 OAuth2 推送授權請求端點 的能力。它定義了擴充套件點,允許您自定義 OAuth2 推送授權請求 的預處理、主處理和後處理邏輯。

OAuth2PushedAuthorizationRequestEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
				.pushedAuthorizationRequestEndpoint(pushedAuthorizationRequestEndpoint ->
					pushedAuthorizationRequestEndpoint
        				.pushedAuthorizationRequestConverter(pushedAuthorizationRequestConverter)   (1)
                        .pushedAuthorizationRequestConverters(pushedAuthorizationRequestConvertersConsumer) (2)
                        .authenticationProvider(authenticationProvider) (3)
                        .authenticationProviders(authenticationProvidersConsumer)   (4)
                        .pushedAuthorizationResponseHandler(pushedAuthorizationResponseHandler) (5)
                        .errorResponseHandler(errorResponseHandler) (6)
				)
		);

	return http.build();
}
1 pushedAuthorizationRequestConverter():新增一個 AuthenticationConverter (預處理器),用於嘗試將 OAuth2 推送授權請求HttpServletRequest 提取到 OAuth2PushedAuthorizationRequestAuthenticationToken 例項。
2 pushedAuthorizationRequestConverters():設定 Consumer,提供對預設和(可選)新增的 AuthenticationConverter 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationConverter
3 authenticationProvider():新增一個 AuthenticationProvider (主處理器),用於驗證 OAuth2PushedAuthorizationRequestAuthenticationToken
4 authenticationProviders():設定 Consumer,提供對預設和(可選)新增的 AuthenticationProvider 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationProvider
5 pushedAuthorizationResponseHandler()AuthenticationSuccessHandler (後處理器),用於處理“已認證”的 OAuth2PushedAuthorizationRequestAuthenticationToken 並返回 OAuth2 推送授權響應
6 errorResponseHandler()AuthenticationFailureHandler (後處理器),用於處理 OAuth2AuthenticationException 並返回 OAuth2Error 響應

OAuth2PushedAuthorizationRequestEndpointConfigurer 配置 OAuth2PushedAuthorizationRequestEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @BeanOAuth2PushedAuthorizationRequestEndpointFilter 是處理 OAuth2 推送授權請求的 Filter

OAuth2PushedAuthorizationRequestEndpointFilter 配置了以下預設值

  • AuthenticationConverter — 由 OAuth2AuthorizationCodeRequestAuthenticationConverter 組成的 DelegatingAuthenticationConverter

  • AuthenticationManager — 由 OAuth2PushedAuthorizationRequestAuthenticationProvider 組成的 AuthenticationManager

  • AuthenticationSuccessHandler — 一個內部實現,用於處理“已認證”的 OAuth2PushedAuthorizationRequestAuthenticationToken 並返回 OAuth2 推送授權響應。

  • AuthenticationFailureHandler — 一個 OAuth2ErrorAuthenticationFailureHandler

自定義推送授權請求驗證

OAuth2AuthorizationCodeRequestAuthenticationValidator 是用於驗證授權碼授權中特定 OAuth2 推送授權請求引數的預設驗證器。預設實現驗證 redirect_uriscope 引數。如果驗證失敗,將丟擲 OAuth2AuthorizationCodeRequestAuthenticationException

OAuth2PushedAuthorizationRequestAuthenticationProvider 透過向 setAuthenticationValidator() 提供型別為 Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> 的自定義身份驗證驗證器,提供了覆蓋預設推送授權請求驗證的能力。

OAuth2AuthorizationCodeRequestAuthenticationContext 包含 OAuth2AuthorizationCodeRequestAuthenticationToken,其中包含 OAuth2 推送授權請求引數。
如果驗證失敗,身份驗證驗證器 必須 丟擲 OAuth2AuthorizationCodeRequestAuthenticationException

在開發生命週期階段,一個常見的用例是允許 redirect_uri 引數中的 localhost

以下示例展示瞭如何使用自定義身份驗證驗證器配置 OAuth2PushedAuthorizationRequestAuthenticationProvider,該驗證器允許 redirect_uri 引數中的 localhost

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
				.pushedAuthorizationRequestEndpoint(pushedAuthorizationRequestEndpoint ->
					pushedAuthorizationRequestEndpoint
                        .authenticationProviders(configureAuthenticationValidator())
				)
		);

	return http.build();
}

private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
	return (authenticationProviders) ->
		authenticationProviders.forEach((authenticationProvider) -> {
			if (authenticationProvider instanceof OAuth2PushedAuthorizationRequestAuthenticationProvider) {
				Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> authenticationValidator =
					// Override default redirect_uri validator
					new CustomRedirectUriValidator()
						// Reuse default scope validator
						.andThen(OAuth2AuthorizationCodeRequestAuthenticationValidator.DEFAULT_SCOPE_VALIDATOR);

				((OAuth2PushedAuthorizationRequestAuthenticationProvider) authenticationProvider)
					.setAuthenticationValidator(authenticationValidator);
			}
		});
}

static class CustomRedirectUriValidator implements Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> {

	@Override
	public void accept(OAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext) {
		OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication =
			authenticationContext.getAuthentication();
		RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
		String requestedRedirectUri = authorizationCodeRequestAuthentication.getRedirectUri();

		// Use exact string matching when comparing client redirect URIs against pre-registered URIs
		if (!registeredClient.getRedirectUris().contains(requestedRedirectUri)) {
			OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST);
			throw new OAuth2AuthorizationCodeRequestAuthenticationException(error, null);
		}
	}
}

OAuth2 裝置授權端點

OAuth2DeviceAuthorizationEndpointConfigurer 提供了自定義 OAuth2 裝置授權端點 的能力。它定義了擴充套件點,允許您自定義 OAuth2 裝置授權請求的預處理、主處理和後處理邏輯。

OAuth2DeviceAuthorizationEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
				.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
                    deviceAuthorizationEndpoint
                        .deviceAuthorizationRequestConverter(deviceAuthorizationRequestConverter)   (1)
                        .deviceAuthorizationRequestConverters(deviceAuthorizationRequestConvertersConsumer) (2)
                        .authenticationProvider(authenticationProvider) (3)
                        .authenticationProviders(authenticationProvidersConsumer)   (4)
                        .deviceAuthorizationResponseHandler(deviceAuthorizationResponseHandler) (5)
                        .errorResponseHandler(errorResponseHandler) (6)
                        .verificationUri("/oauth2/v1/device_verification")  (7)
				)
		);

	return http.build();
}
1 deviceAuthorizationRequestConverter():新增一個 AuthenticationConverter (預處理器),用於嘗試將 OAuth2 裝置授權請求HttpServletRequest 提取到 OAuth2DeviceAuthorizationRequestAuthenticationToken 例項。
2 deviceAuthorizationRequestConverters():設定 Consumer,提供對預設和(可選)新增的 AuthenticationConverter 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationConverter
3 authenticationProvider():新增一個 AuthenticationProvider (主處理器),用於驗證 OAuth2DeviceAuthorizationRequestAuthenticationToken
4 authenticationProviders():設定 Consumer,提供對預設和(可選)新增的 AuthenticationProvider 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationProvider
5 deviceAuthorizationResponseHandler()AuthenticationSuccessHandler (後處理器),用於處理“已認證”的 OAuth2DeviceAuthorizationRequestAuthenticationToken 並返回 OAuth2DeviceAuthorizationResponse
6 errorResponseHandler()AuthenticationFailureHandler (後處理器),用於處理 OAuth2AuthenticationException 並返回 OAuth2Error 響應
7 verificationUri():自定義終端使用者驗證頁面的 URI,用於在輔助裝置上引導資源所有者。

OAuth2DeviceAuthorizationEndpointConfigurer 配置 OAuth2DeviceAuthorizationEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @BeanOAuth2DeviceAuthorizationEndpointFilter 是處理 OAuth2 裝置授權請求的 Filter

OAuth2DeviceAuthorizationEndpointFilter 配置了以下預設值

  • AuthenticationConverter — 一個 OAuth2DeviceAuthorizationRequestAuthenticationConverter

  • AuthenticationManager — 由 OAuth2DeviceAuthorizationRequestAuthenticationProvider 組成的 AuthenticationManager

  • AuthenticationSuccessHandler — 一個內部實現,用於處理“已認證”的 OAuth2DeviceAuthorizationRequestAuthenticationToken 並返回 OAuth2DeviceAuthorizationResponse

  • AuthenticationFailureHandler — 一個 OAuth2ErrorAuthenticationFailureHandler

OAuth2 裝置驗證端點

OAuth2DeviceVerificationEndpointConfigurer 提供了自定義 OAuth2 裝置驗證端點 (或“使用者互動”) 的能力。它定義了擴充套件點,允許您自定義 OAuth2 裝置驗證請求的預處理、主處理和後處理邏輯。

OAuth2DeviceVerificationEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
				.deviceVerificationEndpoint(deviceVerificationEndpoint ->
                    deviceVerificationEndpoint
                        .deviceVerificationRequestConverter(deviceVerificationRequestConverter) (1)
                        .deviceVerificationRequestConverters(deviceVerificationRequestConvertersConsumer)   (2)
                        .authenticationProvider(authenticationProvider) (3)
                        .authenticationProviders(authenticationProvidersConsumer)   (4)
                        .deviceVerificationResponseHandler(deviceVerificationResponseHandler)   (5)
                        .errorResponseHandler(errorResponseHandler) (6)
                        .consentPage("/oauth2/v1/consent")  (7)
				)
		);

	return http.build();
}
1 deviceVerificationRequestConverter():新增一個 AuthenticationConverter (預處理器),用於嘗試將 OAuth2 裝置驗證請求 (或同意) 從 HttpServletRequest 提取到 OAuth2DeviceVerificationAuthenticationTokenOAuth2DeviceAuthorizationConsentAuthenticationToken 例項。
2 deviceVerificationRequestConverters():設定 Consumer,提供對預設和(可選)新增的 AuthenticationConverter 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationConverter
3 authenticationProvider():新增一個 AuthenticationProvider (主處理器),用於驗證 OAuth2DeviceVerificationAuthenticationTokenOAuth2DeviceAuthorizationConsentAuthenticationToken
4 authenticationProviders():設定 Consumer,提供對預設和(可選)新增的 AuthenticationProvider 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationProvider
5 deviceVerificationResponseHandler()AuthenticationSuccessHandler (後處理器),用於處理“已認證”的 OAuth2DeviceVerificationAuthenticationToken 並引導資源所有者返回其裝置。
6 errorResponseHandler()AuthenticationFailureHandler (後處理器),用於處理 OAuth2AuthenticationException 並返回錯誤響應。
7 consentPage():自定義同意頁面的 URI,如果裝置驗證請求流程中需要同意,則重定向資源所有者到該頁面。

OAuth2DeviceVerificationEndpointConfigurer 配置 OAuth2DeviceVerificationEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @BeanOAuth2DeviceVerificationEndpointFilter 是處理 OAuth2 裝置驗證請求(和同意)的 Filter

OAuth2DeviceVerificationEndpointFilter 配置了以下預設值

  • AuthenticationConverter — 由 OAuth2DeviceVerificationAuthenticationConverterOAuth2DeviceAuthorizationConsentAuthenticationConverter 組成的 DelegatingAuthenticationConverter

  • AuthenticationManager — 由 OAuth2DeviceVerificationAuthenticationProviderOAuth2DeviceAuthorizationConsentAuthenticationProvider 組成的 AuthenticationManager

  • AuthenticationSuccessHandler — 一個 SimpleUrlAuthenticationSuccessHandler,用於處理“已認證”的 OAuth2DeviceVerificationAuthenticationToken 並將使用者重定向到成功頁面(/?success)。

  • AuthenticationFailureHandler — 一個內部實現,它使用與 OAuth2AuthenticationException 關聯的 OAuth2Error 並返回 OAuth2Error 響應。

OAuth2 令牌端點

OAuth2TokenEndpointConfigurer 提供了自定義 OAuth2 令牌端點 的能力。它定義了擴充套件點,允許您自定義 OAuth2 訪問令牌請求 的預處理、主處理和後處理邏輯。

OAuth2TokenEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
				.tokenEndpoint(tokenEndpoint ->
                    tokenEndpoint
                        .accessTokenRequestConverter(accessTokenRequestConverter)   (1)
                        .accessTokenRequestConverters(accessTokenRequestConvertersConsumer) (2)
                        .authenticationProvider(authenticationProvider) (3)
                        .authenticationProviders(authenticationProvidersConsumer)   (4)
                        .accessTokenResponseHandler(accessTokenResponseHandler) (5)
                        .errorResponseHandler(errorResponseHandler) (6)
				)
		);

	return http.build();
}
1 accessTokenRequestConverter():新增一個 AuthenticationConverter (預處理器),用於嘗試將 OAuth2 訪問令牌請求HttpServletRequest 提取到 OAuth2AuthorizationGrantAuthenticationToken 例項。
2 accessTokenRequestConverters():設定 Consumer,提供對預設和(可選)新增的 AuthenticationConverter 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationConverter
3 authenticationProvider():新增一個 AuthenticationProvider (主處理器),用於驗證 OAuth2AuthorizationGrantAuthenticationToken
4 authenticationProviders():設定 Consumer,提供對預設和(可選)新增的 AuthenticationProvider 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationProvider
5 accessTokenResponseHandler()AuthenticationSuccessHandler (後處理器),用於處理 OAuth2AccessTokenAuthenticationToken 並返回 OAuth2AccessTokenResponse
6 errorResponseHandler()AuthenticationFailureHandler (後處理器),用於處理 OAuth2AuthenticationException 並返回 OAuth2Error 響應

OAuth2TokenEndpointConfigurer 配置 OAuth2TokenEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @BeanOAuth2TokenEndpointFilter 是處理 OAuth2 訪問令牌請求的 Filter

支援的 授權型別authorization_coderefresh_tokenclient_credentialsurn:ietf:params:oauth:grant-type:device_codeurn:ietf:params:oauth:grant-type:token_exchange

OAuth2TokenEndpointFilter 配置了以下預設值

  • AuthenticationConverter — 由 OAuth2AuthorizationCodeAuthenticationConverterOAuth2RefreshTokenAuthenticationConverterOAuth2ClientCredentialsAuthenticationConverterOAuth2DeviceCodeAuthenticationConverterOAuth2TokenExchangeAuthenticationConverter 組成的 DelegatingAuthenticationConverter

  • AuthenticationManager — 由 OAuth2AuthorizationCodeAuthenticationProviderOAuth2RefreshTokenAuthenticationProviderOAuth2ClientCredentialsAuthenticationProviderOAuth2DeviceCodeAuthenticationProviderOAuth2TokenExchangeAuthenticationProvider 組成的 AuthenticationManager

  • AuthenticationSuccessHandler — 一個 OAuth2AccessTokenResponseAuthenticationSuccessHandler

  • AuthenticationFailureHandler — 一個 OAuth2ErrorAuthenticationFailureHandler

自定義客戶端憑證授權請求驗證

OAuth2ClientCredentialsAuthenticationValidator 是用於驗證特定 OAuth2 客戶端憑證授權請求引數的預設驗證器。預設實現驗證 scope 引數。如果驗證失敗,將丟擲 OAuth2AuthenticationException

OAuth2ClientCredentialsAuthenticationProvider 透過向 setAuthenticationValidator() 提供型別為 Consumer<OAuth2ClientCredentialsAuthenticationContext> 的自定義身份驗證驗證器,提供了覆蓋預設請求驗證的能力。

OAuth2ClientCredentialsAuthenticationContext 包含 OAuth2ClientCredentialsAuthenticationToken,其中包含 OAuth2 客戶端憑證授權請求引數。
如果驗證失敗,身份驗證驗證器 必須 丟擲 OAuth2AuthenticationException

以下示例展示瞭如何使用自定義身份驗證驗證器配置 OAuth2ClientCredentialsAuthenticationProvider,該驗證器覆蓋了預設的 scope 驗證

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
				.tokenEndpoint(tokenEndpoint ->
                    tokenEndpoint
                        .authenticationProviders(configureAuthenticationValidator())
				)
		);

	return http.build();
}

private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
	return (authenticationProviders) ->
		authenticationProviders.forEach((authenticationProvider) -> {
			if (authenticationProvider instanceof OAuth2ClientCredentialsAuthenticationProvider) {
				Consumer<OAuth2ClientCredentialsAuthenticationContext> authenticationValidator =
					new CustomScopeValidator();

				// Override default scope validation
				((OAuth2ClientCredentialsAuthenticationProvider) authenticationProvider)
					.setAuthenticationValidator(authenticationValidator);
			}
		});
}

static class CustomScopeValidator implements Consumer<OAuth2ClientCredentialsAuthenticationContext> {

	@Override
	public void accept(OAuth2ClientCredentialsAuthenticationContext authenticationContext) {
		OAuth2ClientCredentialsAuthenticationToken clientCredentialsAuthentication =
			authenticationContext.getAuthentication();

		Set<String> requestedScopes = clientCredentialsAuthentication.getScopes();
		RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
		Set<String> allowedScopes = registeredClient.getScopes();

        // TODO Implement scope validation

	}
}

DPoP 繫結的訪問令牌

RFC 9449 OAuth 2.0 證明持有(DPoP)是一種用於傳送方約束訪問令牌的應用層機制。

DPoP 的主要目標是透過授權伺服器在頒發訪問令牌時將其繫結到公鑰,並要求客戶端在使用訪問令牌訪問資源伺服器時證明持有相應的私鑰,從而防止未經授權或非法的客戶端使用洩露或被盜的訪問令牌。

透過 DPoP 進行傳送方約束的訪問令牌與典型的持有者令牌(任何持有訪問令牌的客戶端都可以使用)形成對比。

DPoP 引入了 DPoP 證明的概念,它是由客戶端建立並作為 HTTP 請求頭髮送的 JWT。客戶端使用 DPoP 證明來證明持有與特定公鑰對應的私鑰。

當客戶端發起訪問令牌請求時,它會在 HTTP 頭中附加 DPoP 證明。授權伺服器將訪問令牌繫結(傳送方約束)到 DPoP 證明中關聯的公鑰。

當客戶端發起受保護資源請求時,它再次在 HTTP 頭中附加 DPoP 證明。

資源伺服器獲取與訪問令牌繫結的公鑰資訊,可以直接從訪問令牌(JWT)中獲取,也可以透過 OAuth2 令牌自省端點 獲取。然後,資源伺服器驗證與訪問令牌繫結的公鑰是否與 DPoP 證明中的公鑰匹配。它還驗證 DPoP 證明中的訪問令牌雜湊是否與請求中的訪問令牌匹配。

DPoP 訪問令牌請求

要使用 DPoP 請求繫結到公鑰的訪問令牌,客戶端在向 OAuth2 令牌端點發出訪問令牌請求時,必須DPoP 頭中提供有效的 DPoP 證明。這適用於所有訪問令牌請求,無論授權型別如何(例如 authorization_coderefresh_tokenclient_credentials 等)。

以下 HTTP 請求顯示了一個在 DPoP 頭中包含 DPoP 證明的 authorization_code 訪問令牌請求

POST /oauth2/token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJraWQiOiJyc2EtandrLWtpZCIsInR5cCI6ImRwb3Arand0IiwiYWxnIjoiUlMyNTYiLCJqd2siOnsia3R5IjoiUlNBIiwiZSI6IkFRQUIiLCJraWQiOiJyc2EtandrLWtpZCIsIm4iOiIzRmxxSnI1VFJza0lRSWdkRTNEZDdEOWxib1dkY1RVVDhhLWZKUjdNQXZRbTdYWE5vWWttM3Y3TVFMMU5ZdER2TDJsOENBbmMwV2RTVElOVTZJUnZjNUtxbzJRNGNzTlg5U0hPbUVmem9ST2pRcWFoRWN2ZTFqQlhsdW9DWGRZdVlweDRfMXRmUmdHNmlpNFVoeGg2aUk4cU5NSlFYLWZMZnFoYmZZZnhCUVZSUHl3QmtBYklQNHgxRUFzYkM2RlNObWtoQ3hpTU5xRWd4YUlwWThDMmtKZEpfWklWLVdXNG5vRGR6cEtxSGN3bUI4RnNydW1sVllfRE5WdlVTRElpcGlxOVBiUDRIOTlUWE4xbzc0Nm9SYU5hMDdycTFob0NnTVNTeS04NVNhZ0NveGxteUUtRC1vZjlTc01ZOE9sOXQwcmR6cG9iQnVoeUpfbzVkZnZqS3cifX0.eyJodG0iOiJQT1NUIiwiaHR1IjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20vb2F1dGgyL3Rva2VuIiwiaWF0IjoxNzQ2ODA2MzA1LCJqdGkiOiI0YjIzNDBkMi1hOTFmLTQwYTUtYmFhOS1kZDRlNWRlYWM4NjcifQ.wq8gJ_G6vpiEinfaY3WhereqCCLoeJOG8tnWBBAzRWx9F1KU5yAAWq-ZVCk_k07-h6DIqz2wgv6y9dVbNpRYwNwDUeik9qLRsC60M8YW7EFVyI3n_NpujLwzZeub_nDYMVnyn4ii0NaZrYHtoGXOlswQfS_-ET-jpC0XWm5nBZsCdUEXjOYtwaACC6Js-pyNwKmSLp5SKIk11jZUR5xIIopaQy521y9qJHhGRwzj8DQGsP7wMZ98UFL0E--1c-hh4rTy8PMeWCqRHdwjj_ry_eTe0DJFcxxYQdeL7-0_0CIO4Ayx5WHEpcUOIzBRoN32RsNpDZc-5slDNj9ku004DA

grant_type=authorization_code\
&client_id=s6BhdRkqt\
&code=SplxlOBeZQQYbYS6WxSbIA\
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb\
&code_verifier=bEaL42izcC-o-xBk0K2vuJ6U-y1p9r_wW2dFWIWgjz-

以下顯示了 DPoP 證明 JWT 頭和宣告的表示

{
  "typ": "dpop+jwt",
  "alg": "RS256",
  "jwk": {
    "kty": "RSA",
    "e": "AQAB",
    "n": "3FlqJr5TRskIQIgdE3Dd7D9lboWdcTUT8a-fJR7MAvQm7XXNoYkm3v7MQL1NYtDvL2l8CAnc0WdSTINU6IRvc5Kqo2Q4csNX9SHOmEfzoROjQqahEcve1jBXluoCXdYuYpx4_1tfRgG6ii4Uhxh6iI8qNMJQX-fLfqhbfYfxBQVRPywBkAbIP4x1EAsbC6FSNmkhCxiMNqEgxaIpY8C2kJdJ_ZIV-WW4noDdzpKqHcwmB8FsrumlVY_DNVvUSDIipiq9PbP4H99TXN1o746oRaNa07rq1hoCgMSSy-85SagCoxlmyE-D-of9SsMY8Ol9t0rdzpobBuhyJ_o5dfvjKw"
  }
}
{
  "htm": "POST",
  "htu": "https://server.example.com/oauth2/token",
  "iat": 1746806305,
  "jti": "4b2340d2-a91f-40a5-baa9-dd4e5deac867"
}

以下程式碼顯示瞭如何生成 DPoP 證明 JWT 的示例

RSAKey rsaKey = ...
JWKSource<SecurityContext> jwkSource = (jwkSelector, securityContext) -> jwkSelector
		.select(new JWKSet(rsaKey));
NimbusJwtEncoder jwtEncoder = new NimbusJwtEncoder(jwkSource);

JwsHeader jwsHeader = JwsHeader.with(SignatureAlgorithm.RS256)
		.type("dpop+jwt")
		.jwk(rsaKey.toPublicJWK().toJSONObject())
		.build();
JwtClaimsSet claims = JwtClaimsSet.builder()
		.issuedAt(Instant.now())
		.claim("htm", "POST")
		.claim("htu", "https://server.example.com/oauth2/token")
		.id(UUID.randomUUID().toString())
		.build();

Jwt dPoPProof = jwtEncoder.encode(JwtEncoderParameters.from(jwsHeader, claims));

授權伺服器成功驗證 DPoP 證明後,DPoP 證明中的公鑰將被繫結(傳送方約束)到頒發的訪問令牌。

以下訪問令牌響應顯示 token_type 引數為 DPoP,以向客戶端表明訪問令牌已繫結到其 DPoP 證明公鑰

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
 "access_token": "Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU",
 "token_type": "DPoP",
 "expires_in": 2677
}

公鑰確認

資源伺服器必須能夠識別訪問令牌是否為 DPoP 繫結,並驗證與 DPoP 證明公鑰的繫結。繫結是透過將公鑰與訪問令牌關聯起來,以便資源伺服器可以訪問,例如直接在訪問令牌中嵌入公鑰雜湊(JWT)或透過令牌內省。

當訪問令牌表示為 JWT 時,公鑰雜湊包含在確認方法(cnf)宣告下的 jkt 宣告中。

以下示例顯示了包含 cnf 宣告和 jkt 宣告的 JWT 訪問令牌的宣告,其中 jkt 是 DPoP 證明公鑰的 JWK SHA-256 指紋

{
  "sub":"[email protected]",
  "iss":"https://server.example.com",
  "nbf":1562262611,
  "exp":1562266216,
  "cnf":
  {
    "jkt":"CQMknzRoZ5YUi7vS58jck1q8TmZT8wiIiXrCN1Ny4VU"
  }
}

OAuth2 令牌自省端點

OAuth2TokenIntrospectionEndpointConfigurer 提供了自定義 OAuth2 令牌自省端點 的能力。它定義了擴充套件點,允許您自定義 OAuth2 自省請求 的預處理、主處理和後處理邏輯。

OAuth2TokenIntrospectionEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
				.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint ->
                    tokenIntrospectionEndpoint
                        .introspectionRequestConverter(introspectionRequestConverter)   (1)
                        .introspectionRequestConverters(introspectionRequestConvertersConsumer) (2)
                        .authenticationProvider(authenticationProvider) (3)
                        .authenticationProviders(authenticationProvidersConsumer)   (4)
                        .introspectionResponseHandler(introspectionResponseHandler) (5)
                        .errorResponseHandler(errorResponseHandler) (6)
				)
		);

	return http.build();
}
1 introspectionRequestConverter():新增一個 AuthenticationConverter (預處理器),用於嘗試將 OAuth2 自省請求HttpServletRequest 提取到 OAuth2TokenIntrospectionAuthenticationToken 例項。
2 introspectionRequestConverters():設定 Consumer,提供對預設和(可選)新增的 AuthenticationConverter 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationConverter
3 authenticationProvider():新增一個 AuthenticationProvider (主處理器),用於驗證 OAuth2TokenIntrospectionAuthenticationToken
4 authenticationProviders():設定 Consumer,提供對預設和(可選)新增的 AuthenticationProvider 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationProvider
5 introspectionResponseHandler()AuthenticationSuccessHandler (後處理器),用於處理“已認證”的 OAuth2TokenIntrospectionAuthenticationToken 並返回 OAuth2TokenIntrospection 響應
6 errorResponseHandler()AuthenticationFailureHandler (後處理器),用於處理 OAuth2AuthenticationException 並返回 OAuth2Error 響應

OAuth2TokenIntrospectionEndpointConfigurer 配置 OAuth2TokenIntrospectionEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @BeanOAuth2TokenIntrospectionEndpointFilter 是處理 OAuth2 自省請求的 Filter

OAuth2TokenIntrospectionEndpointFilter 配置了以下預設值

  • AuthenticationConverter — 一個 OAuth2TokenIntrospectionAuthenticationConverter

  • AuthenticationManager — 由 OAuth2TokenIntrospectionAuthenticationProvider 組成的 AuthenticationManager

  • AuthenticationSuccessHandler — 一個內部實現,用於處理“已認證”的 OAuth2TokenIntrospectionAuthenticationToken 並返回 OAuth2TokenIntrospection 響應。

  • AuthenticationFailureHandler — 一個 OAuth2ErrorAuthenticationFailureHandler

OAuth2 令牌撤銷端點

OAuth2TokenRevocationEndpointConfigurer 提供了自定義 OAuth2 令牌撤銷端點 的能力。它定義了擴充套件點,允許您自定義 OAuth2 撤銷請求 的預處理、主處理和後處理邏輯。

OAuth2TokenRevocationEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
				.tokenRevocationEndpoint(tokenRevocationEndpoint ->
                    tokenRevocationEndpoint
                        .revocationRequestConverter(revocationRequestConverter) (1)
                        .revocationRequestConverters(revocationRequestConvertersConsumer)   (2)
                        .authenticationProvider(authenticationProvider) (3)
                        .authenticationProviders(authenticationProvidersConsumer)   (4)
                        .revocationResponseHandler(revocationResponseHandler)   (5)
                        .errorResponseHandler(errorResponseHandler) (6)
				)
		);

	return http.build();
}
1 revocationRequestConverter():新增一個 AuthenticationConverter (預處理器),用於嘗試將 OAuth2 撤銷請求HttpServletRequest 提取到 OAuth2TokenRevocationAuthenticationToken 例項。
2 revocationRequestConverters():設定 Consumer,提供對預設和(可選)新增的 AuthenticationConverter 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationConverter
3 authenticationProvider():新增一個 AuthenticationProvider (主處理器),用於驗證 OAuth2TokenRevocationAuthenticationToken
4 authenticationProviders():設定 Consumer,提供對預設和(可選)新增的 AuthenticationProvider 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationProvider
5 revocationResponseHandler()AuthenticationSuccessHandler (後處理器),用於處理“已認證”的 OAuth2TokenRevocationAuthenticationToken 並返回 OAuth2 撤銷響應
6 errorResponseHandler()AuthenticationFailureHandler (後處理器),用於處理 OAuth2AuthenticationException 並返回 OAuth2Error 響應

OAuth2TokenRevocationEndpointConfigurer 配置 OAuth2TokenRevocationEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @BeanOAuth2TokenRevocationEndpointFilter 是處理 OAuth2 撤銷請求的 Filter

OAuth2TokenRevocationEndpointFilter 配置了以下預設值

  • AuthenticationConverter — 一個 OAuth2TokenRevocationAuthenticationConverter

  • AuthenticationManager — 由 OAuth2TokenRevocationAuthenticationProvider 組成的 AuthenticationManager

  • AuthenticationSuccessHandler — 一個內部實現,用於處理“已認證”的 OAuth2TokenRevocationAuthenticationToken 並返回 OAuth2 撤銷響應。

  • AuthenticationFailureHandler — 一個 OAuth2ErrorAuthenticationFailureHandler

OAuth2 授權伺服器元資料端點

OAuth2AuthorizationServerMetadataEndpointConfigurer 提供了自定義 OAuth2 授權伺服器元資料端點 的能力。它定義了一個擴充套件點,允許您自定義 OAuth2 授權伺服器元資料響應

OAuth2AuthorizationServerMetadataEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
				.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint ->
                    authorizationServerMetadataEndpoint
                        .authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer)   (1)
				)
		);

	return http.build();
}
1 authorizationServerMetadataCustomizer()Consumer,提供對 OAuth2AuthorizationServerMetadata.Builder 的訪問,允許自定義授權伺服器配置的宣告。

OAuth2AuthorizationServerMetadataEndpointConfigurer 配置 OAuth2AuthorizationServerMetadataEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @BeanOAuth2AuthorizationServerMetadataEndpointFilter 是返回 OAuth2AuthorizationServerMetadata 響應Filter

JWK 設定端點

OAuth2AuthorizationServerConfigurer 支援 JWK 設定端點

OAuth2AuthorizationServerConfigurer 配置 NimbusJwkSetEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @BeanNimbusJwkSetEndpointFilter 是返回 JWK 集Filter

JWK Set 端點僅在註冊了 JWKSource<SecurityContext> @Bean 時才配置。

OpenID Connect 1.0 提供者配置端點

OidcProviderConfigurationEndpointConfigurer 提供了自定義 OpenID Connect 1.0 提供者配置端點 的能力。它定義了一個擴充套件點,允許您自定義 OpenID 提供者配置響應

OidcProviderConfigurationEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
                .oidc(oidc ->
                    oidc
                        .providerConfigurationEndpoint(providerConfigurationEndpoint ->
                            providerConfigurationEndpoint
                                .providerConfigurationCustomizer(providerConfigurationCustomizer)   (1)
                        )
                )
		);

	return http.build();
}
1 providerConfigurationCustomizer()Consumer,提供對 OidcProviderConfiguration.Builder 的訪問,允許自定義 OpenID 提供者配置的宣告。

OidcProviderConfigurationEndpointConfigurer 配置 OidcProviderConfigurationEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @BeanOidcProviderConfigurationEndpointFilter 是返回 OidcProviderConfiguration 響應Filter

OpenID Connect 1.0 登出端點

OidcLogoutEndpointConfigurer 提供了自定義 OpenID Connect 1.0 登出端點 的能力。它定義了擴充套件點,允許您自定義 RP 發起的登出請求的預處理、主處理和後處理邏輯。

OidcLogoutEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
                .oidc(oidc ->
                    oidc
                        .logoutEndpoint(logoutEndpoint ->
                            logoutEndpoint
                                .logoutRequestConverter(logoutRequestConverter) (1)
                                .logoutRequestConverters(logoutRequestConvertersConsumer)   (2)
                                .authenticationProvider(authenticationProvider) (3)
                                .authenticationProviders(authenticationProvidersConsumer)   (4)
                                .logoutResponseHandler(logoutResponseHandler)   (5)
                                .errorResponseHandler(errorResponseHandler) (6)
                        )
                )
		);

	return http.build();
}
1 logoutRequestConverter():新增一個 AuthenticationConverter (預處理器),用於嘗試將 登出請求HttpServletRequest 提取到 OidcLogoutAuthenticationToken 例項。
2 logoutRequestConverters():設定 Consumer,提供對預設和(可選)新增的 AuthenticationConverter 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationConverter
3 authenticationProvider():新增一個 AuthenticationProvider (主處理器),用於驗證 OidcLogoutAuthenticationToken
4 authenticationProviders():設定 Consumer,提供對預設和(可選)新增的 AuthenticationProvider 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationProvider
5 logoutResponseHandler()AuthenticationSuccessHandler (後處理器),用於處理“已認證”的 OidcLogoutAuthenticationToken 並執行登出。
6 errorResponseHandler()AuthenticationFailureHandler (後處理器),用於處理 OAuth2AuthenticationException 並返回錯誤響應。

OidcLogoutEndpointConfigurer 配置 OidcLogoutEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @BeanOidcLogoutEndpointFilter 是處理 RP 發起的登出請求 並執行終端使用者登出的 Filter

OidcLogoutEndpointFilter 配置了以下預設值

  • AuthenticationConverter — 一個 OidcLogoutAuthenticationConverter

  • AuthenticationManager — 由 OidcLogoutAuthenticationProvider 組成的 AuthenticationManager

  • AuthenticationSuccessHandler — 一個 OidcLogoutAuthenticationSuccessHandler

  • AuthenticationFailureHandler — 一個內部實現,它使用與 OAuth2AuthenticationException 關聯的 OAuth2Error 並返回 OAuth2Error 響應。

OidcLogoutAuthenticationProvider 使用 SessionRegistry 查詢與請求登出的終端使用者關聯的 SessionInformation 例項。
OidcClientInitiatedLogoutSuccessHandler 是 Spring Security 的 OAuth2 客戶端支援中用於配置 OpenID Connect 1.0 RP 發起的登出 的相應配置。

自定義登出請求驗證

OidcLogoutAuthenticationValidator 是用於驗證特定 OpenID Connect RP 發起的登出請求引數的預設驗證器。預設實現驗證 post_logout_redirect_uri 引數。如果驗證失敗,將丟擲 OAuth2AuthenticationException

OidcLogoutAuthenticationProvider 透過向 setAuthenticationValidator() 提供型別為 Consumer<OidcLogoutAuthenticationContext> 的自定義身份驗證驗證器,提供了覆蓋預設登出請求驗證的能力。

OidcLogoutAuthenticationContext 包含 OidcLogoutAuthenticationToken,其中包含登出請求引數。
如果驗證失敗,身份驗證驗證器 必須 丟擲 OAuth2AuthenticationException

以下示例展示瞭如何使用自定義身份驗證驗證器配置 OidcLogoutAuthenticationProvider

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
                .oidc(oidc ->
                    oidc
                        .logoutEndpoint(logoutEndpoint ->
                            logoutEndpoint
                                .authenticationProviders(configureAuthenticationValidator())
                        )
                )
		);

	return http.build();
}

private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
	return (authenticationProviders) ->
			authenticationProviders.forEach((authenticationProvider) -> {
				if (authenticationProvider instanceof OidcLogoutAuthenticationProvider oidcLogoutAuthenticationProvider) {
					Consumer<OidcLogoutAuthenticationContext> authenticationValidator = new CustomPostLogoutRedirectUriValidator();
					oidcLogoutAuthenticationProvider.setAuthenticationValidator(authenticationValidator);
				}
			});
}

static class CustomPostLogoutRedirectUriValidator implements Consumer<OidcLogoutAuthenticationContext> {

	@Override
	public void accept(OidcLogoutAuthenticationContext authenticationContext) {
		OidcLogoutAuthenticationToken oidcLogoutAuthentication =
				authenticationContext.getAuthentication();
		RegisteredClient registeredClient = authenticationContext.getRegisteredClient();

		// TODO

	}
}

OpenID Connect 1.0 使用者資訊端點

OidcUserInfoEndpointConfigurer 提供了自定義 OpenID Connect 1.0 使用者資訊端點 的能力。它定義了擴充套件點,允許您自定義 使用者資訊請求 的預處理、主處理和後處理邏輯。

OidcUserInfoEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
                .oidc(oidc ->
                    oidc
                        .userInfoEndpoint(userInfoEndpoint ->
                            userInfoEndpoint
                                .userInfoRequestConverter(userInfoRequestConverter) (1)
                                .userInfoRequestConverters(userInfoRequestConvertersConsumer)   (2)
                                .authenticationProvider(authenticationProvider) (3)
                                .authenticationProviders(authenticationProvidersConsumer)   (4)
                                .userInfoResponseHandler(userInfoResponseHandler)   (5)
                                .errorResponseHandler(errorResponseHandler) (6)
                                .userInfoMapper(userInfoMapper) (7)
                        )
                )
		);

	return http.build();
}
1 userInfoRequestConverter():新增一個 AuthenticationConverter (預處理器),用於嘗試將 使用者資訊請求HttpServletRequest 提取到 OidcUserInfoAuthenticationToken 例項。
2 userInfoRequestConverters():設定 Consumer,提供對預設和(可選)新增的 AuthenticationConverter 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationConverter
3 authenticationProvider():新增一個 AuthenticationProvider (主處理器),用於驗證 OidcUserInfoAuthenticationToken
4 authenticationProviders():設定 Consumer,提供對預設和(可選)新增的 AuthenticationProvider 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationProvider
5 userInfoResponseHandler()AuthenticationSuccessHandler (後處理器),用於處理“已認證”的 OidcUserInfoAuthenticationToken 並返回 使用者資訊響應
6 errorResponseHandler()AuthenticationFailureHandler (後處理器),用於處理 OAuth2AuthenticationException 並返回 使用者資訊錯誤響應
7 userInfoMapper():用於從 OidcUserInfoAuthenticationContext 中提取宣告到 OidcUserInfo 例項的 Function

OidcUserInfoEndpointConfigurer 配置 OidcUserInfoEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @BeanOidcUserInfoEndpointFilter 是處理 使用者資訊請求 並返回 OidcUserInfo 響應Filter

OidcUserInfoEndpointFilter 配置了以下預設值

  • AuthenticationConverter — 一個內部實現,用於從 SecurityContext 獲取 Authentication 並使用 principal 建立 OidcUserInfoAuthenticationToken

  • AuthenticationManager — 由 OidcUserInfoAuthenticationProvider 組成的 AuthenticationManager,該提供者關聯一個 userInfoMapper 的內部實現,它根據授權期間請求的 範圍ID Token 中提取 標準宣告

  • AuthenticationSuccessHandler — 一個內部實現,用於處理“已認證”的 OidcUserInfoAuthenticationToken 並返回 OidcUserInfo 響應。

  • AuthenticationFailureHandler — 一個內部實現,它使用與 OAuth2AuthenticationException 關聯的 OAuth2Error 並返回 OAuth2Error 響應。

您可以透過提供一個 OAuth2TokenCustomizer<JwtEncodingContext> @Bean 來自定義 ID Token。

OpenID Connect 1.0 使用者資訊端點是一個 OAuth2 受保護資源,要求使用者資訊請求 中以持有者令牌的形式傳送訪問令牌。

OAuth2 資源伺服器支援是自動配置的,但是,OpenID Connect 1.0 使用者資訊端點 需要 一個 JwtDecoder @Bean
指南 操作指南:自定義 OpenID Connect 1.0 使用者資訊響應 包含自定義使用者資訊端點的示例。

OpenID Connect 1.0 客戶端註冊端點

OidcClientRegistrationEndpointConfigurer 提供了自定義 OpenID Connect 1.0 客戶端註冊端點 的能力。它定義了擴充套件點,允許您自定義 客戶端註冊請求客戶端讀取請求 的預處理、主處理和後處理邏輯。

OidcClientRegistrationEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
			OAuth2AuthorizationServerConfigurer.authorizationServer();

	http
		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
		.with(authorizationServerConfigurer, (authorizationServer) ->
			authorizationServer
                .oidc(oidc ->
                    oidc
                        .clientRegistrationEndpoint(clientRegistrationEndpoint ->
                            clientRegistrationEndpoint
                                .clientRegistrationRequestConverter(clientRegistrationRequestConverter) (1)
                                .clientRegistrationRequestConverters(clientRegistrationRequestConvertersConsumers)  (2)
                                .authenticationProvider(authenticationProvider) (3)
                                .authenticationProviders(authenticationProvidersConsumer)   (4)
                                .clientRegistrationResponseHandler(clientRegistrationResponseHandler)   (5)
                                .errorResponseHandler(errorResponseHandler) (6)
                        )
                )
		);

	return http.build();
}
1 clientRegistrationRequestConverter():新增一個 AuthenticationConverter (預處理器),用於嘗試將 客戶端註冊請求客戶端讀取請求HttpServletRequest 提取到 OidcClientRegistrationAuthenticationToken 例項。
2 clientRegistrationRequestConverters():設定 Consumer,提供對預設和(可選)新增的 AuthenticationConverter 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationConverter
3 authenticationProvider():新增一個 AuthenticationProvider (主處理器),用於驗證 OidcClientRegistrationAuthenticationToken
4 authenticationProviders():設定 Consumer,提供對預設和(可選)新增的 AuthenticationProvider 列表的訪問,允許新增、刪除或自定義特定的 AuthenticationProvider
5 clientRegistrationResponseHandler()AuthenticationSuccessHandler (後處理器),用於處理“已認證”的 OidcClientRegistrationAuthenticationToken 並返回 客戶端註冊響應客戶端讀取響應
6 errorResponseHandler()AuthenticationFailureHandler (後處理器),用於處理 OAuth2AuthenticationException 並返回 客戶端註冊錯誤響應客戶端讀取錯誤響應
OpenID Connect 1.0 客戶端註冊端點預設停用,因為許多部署不需要動態客戶端註冊。

OidcClientRegistrationEndpointConfigurer 配置 OidcClientRegistrationEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @BeanOidcClientRegistrationEndpointFilter 是處理 客戶端註冊請求 並返回 OidcClientRegistration 響應Filter

OidcClientRegistrationEndpointFilter 還處理 客戶端讀取請求 並返回 OidcClientRegistration 響應

OidcClientRegistrationEndpointFilter 配置了以下預設值

  • AuthenticationConverter — 一個 OidcClientRegistrationAuthenticationConverter

  • AuthenticationManager — 由 OidcClientRegistrationAuthenticationProviderOidcClientConfigurationAuthenticationProvider 組成的 AuthenticationManager

  • AuthenticationSuccessHandler — 一個內部實現,用於處理“已認證”的 OidcClientRegistrationAuthenticationToken 並返回 OidcClientRegistration 響應。

  • AuthenticationFailureHandler — 一個內部實現,它使用與 OAuth2AuthenticationException 關聯的 OAuth2Error 並返回 OAuth2Error 響應。

OpenID Connect 1.0 客戶端註冊端點是一個 OAuth2 受保護資源要求 在客戶端註冊(或客戶端讀取)請求中以持有者令牌的形式傳送訪問令牌。

OAuth2 資源伺服器支援是自動配置的,但是,OpenID Connect 1.0 客戶端註冊端點 需要 一個 JwtDecoder @Bean
客戶端註冊請求中的訪問令牌 需要 OAuth2 範圍 client.create
客戶端讀取請求中的訪問令牌 需要 OAuth2 範圍 client.read
© . This site is unofficial and not affiliated with VMware.