協議端點

OAuth2 授權端點

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

OAuth2AuthorizationEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	http
		.oauth2AuthorizationServer((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 (預處理器),用於嘗試將 HttpServletRequest 中的 OAuth2 授權請求 (或同意) 提取到 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 @Bean 中。OAuth2AuthorizationEndpointFilter 是處理 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 {
	http
		.oauth2AuthorizationServer((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 {
	http
		.oauth2AuthorizationServer((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 (預處理器),用於嘗試將 HttpServletRequest 中的 OAuth2 推送授權請求 提取到 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 @Bean 中。OAuth2PushedAuthorizationRequestEndpointFilter 是處理 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 {
	http
		.oauth2AuthorizationServer((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 {
	http
		.oauth2AuthorizationServer((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 (預處理器),用於嘗試將 HttpServletRequest 中的 OAuth2 裝置授權請求 提取到 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,用於將資源所有者定向到輔助裝置。
OAuth2 裝置授權端點預設停用。

OAuth2DeviceAuthorizationEndpointConfigurer 配置 OAuth2DeviceAuthorizationEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @Bean 中。OAuth2DeviceAuthorizationEndpointFilter 是處理 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 {
	http
		.oauth2AuthorizationServer((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 (預處理器),用於嘗試將 HttpServletRequest 中的 OAuth2 裝置驗證請求 (或同意) 提取到 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,如果在裝置驗證請求流程中需要同意,則重定向資源所有者到該頁面。
OAuth2 裝置驗證端點預設停用。

OAuth2DeviceVerificationEndpointConfigurer 配置 OAuth2DeviceVerificationEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @Bean 中。OAuth2DeviceVerificationEndpointFilter 是處理 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 {
	http
		.oauth2AuthorizationServer((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 (預處理器),用於嘗試將 HttpServletRequest 中的 OAuth2 訪問令牌請求 提取到 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 @Bean 中。OAuth2TokenEndpointFilter 是處理 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 {
	http
		.oauth2AuthorizationServer((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 {
	http
		.oauth2AuthorizationServer((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 (預處理器),用於嘗試將 HttpServletRequest 中的 OAuth2 自省請求 提取到 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 @Bean 中。OAuth2TokenIntrospectionEndpointFilter 是處理 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 {
	http
		.oauth2AuthorizationServer((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 (預處理器),用於嘗試將 HttpServletRequest 中的 OAuth2 撤銷請求 提取到 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 @Bean 中。OAuth2TokenRevocationEndpointFilter 是處理 OAuth2 撤銷請求的 Filter

OAuth2TokenRevocationEndpointFilter 配置了以下預設值

  • AuthenticationConverter — 一個 OAuth2TokenRevocationAuthenticationConverter

  • AuthenticationManager — 由 OAuth2TokenRevocationAuthenticationProvider 組成的 AuthenticationManager

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

  • AuthenticationFailureHandler — 一個 OAuth2ErrorAuthenticationFailureHandler

OAuth2 客戶端註冊端點

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

OAuth2ClientRegistrationEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	http
		.oauth2AuthorizationServer((authorizationServer) ->
			authorizationServer
				.clientRegistrationEndpoint(clientRegistrationEndpoint ->
                    clientRegistrationEndpoint
                        .clientRegistrationRequestConverter(clientRegistrationRequestConverter) (1)
                        .clientRegistrationRequestConverters(clientRegistrationRequestConvertersConsumer)   (2)
                        .authenticationProvider(authenticationProvider) (3)
                        .authenticationProviders(authenticationProvidersConsumer)   (4)
                        .clientRegistrationResponseHandler(clientRegistrationResponseHandler)   (5)
                        .errorResponseHandler(errorResponseHandler) (6)
				)
		);

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

OAuth2ClientRegistrationEndpointConfigurer 配置 OAuth2ClientRegistrationEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @Bean 中。OAuth2ClientRegistrationEndpointFilter 是處理 客戶端註冊請求 並返回 OAuth2ClientRegistration 響應Filter

OAuth2ClientRegistrationEndpointFilter 配置了以下預設值

  • AuthenticationConverter — 一個 OAuth2ClientRegistrationAuthenticationConverter

  • AuthenticationManager — 由 OAuth2ClientRegistrationAuthenticationProvider 組成的 AuthenticationManager

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

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

OAuth2 客戶端註冊端點是一個 OAuth2 受保護資源,它 要求 在客戶端註冊請求中以不記名令牌的形式傳送訪問令牌。

OAuth2 資源伺服器支援已自動配置,但是,OAuth2 客戶端註冊端點 需要 一個 JwtDecoder @Bean
客戶端註冊請求中的訪問令牌 需要 OAuth2 作用域 client.create
要允許開放式客戶端註冊(請求中不帶訪問令牌),請配置 OAuth2ClientRegistrationAuthenticationProvider.setOpenRegistrationAllowed(true)

OAuth2 授權伺服器元資料端點

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

OAuth2AuthorizationServerMetadataEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	http
		.oauth2AuthorizationServer((authorizationServer) ->
			authorizationServer
				.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint ->
                    authorizationServerMetadataEndpoint
                        .authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer)   (1)
				)
		);

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

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

JWK Set 端點

OAuth2AuthorizationServerConfigurer 支援 JWK Set 端點

OAuth2AuthorizationServerConfigurer 配置 NimbusJwkSetEndpointFilter 並將其註冊到 OAuth2 授權伺服器 SecurityFilterChain @Bean 中。NimbusJwkSetEndpointFilter 是返回 JWK SetFilter

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

OpenID Connect 1.0 提供者配置端點

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

OidcProviderConfigurationEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	http
		.oauth2AuthorizationServer((authorizationServer) ->
			authorizationServer
                .oidc(oidc ->
                    oidc
                        .providerConfigurationEndpoint(providerConfigurationEndpoint ->
                            providerConfigurationEndpoint
                                .providerConfigurationCustomizer(providerConfigurationCustomizer)   (1)
                        )
                )
		);

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

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

OpenID Connect 1.0 退出端點

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

OidcLogoutEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	http
		.oauth2AuthorizationServer((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 @Bean 中。OidcLogoutEndpointFilter 是處理 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 {
	http
		.oauth2AuthorizationServer((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 {
	http
		.oauth2AuthorizationServer((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 @Bean 中。OidcUserInfoEndpointFilter 是處理 使用者資訊請求 並返回 OidcUserInfo 響應Filter

OidcUserInfoEndpointFilter 配置了以下預設值

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

  • AuthenticationManager — 一個由 OidcUserInfoAuthenticationProvider 組成的 AuthenticationManager,後者與 userInfoMapper 的內部實現相關聯,該實現根據授權期間 請求的作用域ID 令牌 中提取 標準宣告

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

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

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

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

OAuth2 資源伺服器支援已自動配置,但是,OpenID Connect 1.0 使用者資訊端點 需要 一個 JwtDecoder @Bean

OpenID Connect 1.0 客戶端註冊端點

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

OidcClientRegistrationEndpointConfigurer 提供了以下配置選項

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	http
		.oauth2AuthorizationServer((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 @Bean 中。OidcClientRegistrationEndpointFilter 是處理 客戶端註冊請求 並返回 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.