SpringSecurity中文文档(Servlet OAuth 2.0 Client)

OAuth 2.0 Client

OAuth 2.0 Client 特性提供了对 OAuth 2.0授权框架中定义的 Client 角色的支持。

在高层次,可用的核心特征是:

Authorization Grant support

Client Authentication support

HTTP Client support

  • 用于 Servlet 环境的 WebClient 集成(用于请求受保护的资源)

Oauth2Client () DSL 为定制 OAuth 2.0 Client 使用的核心组件提供了许多配置选项。另外,HttpSecurity.oauth2Client().authorizationCodeGrant()启用授权代码授权的自定义。

下面的代码显示了 HttpSecurity.oauth2Client () DSL 提供的完整配置选项:

OAuth2 Client Configuration Options

@Configuration
@EnableWebSecurity
public class OAuth2ClientSecurityConfig {
   
   

	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
   
   
		http
			.oauth2Client(oauth2 -> oauth2
				.clientRegistrationRepository(this.clientRegistrationRepository())
				.authorizedClientRepository(this.authorizedClientRepository())
				.authorizedClientService(this.authorizedClientService())
				.authorizationCodeGrant(codeGrant -> codeGrant
					.authorizationRequestRepository(this.authorizationRequestRepository())
					.authorizationRequestResolver(this.authorizationRequestResolver())
					.accessTokenResponseClient(this.accessTokenResponseClient())
				)
			);
		return http.build();
	}
}

除了 HttpSecurity.oauth2Client () DSL 之外,还支持 XML 配置。

下面的代码显示了security namespace中可用的完整配置选项:

OAuth2 Client XML Configuration Options

<http>
	<oauth2-client client-registration-repository-ref="clientRegistrationRepository"
				   authorized-client-repository-ref="authorizedClientRepository"
				   authorized-client-service-ref="authorizedClientService">
		<authorization-code-grant
				authorization-request-repository-ref="authorizationRequestRepository"
				authorization-request-resolver-ref="authorizationRequestResolver"
				access-token-response-client-ref="accessTokenResponseClient"/>
	</oauth2-client>
</http>

OAuth2AuthorizedClientManager 与一个或多个 OAuth2AuthorizedClientProvider 协作,负责管理 OAuth 2.0客户端的授权(或重新授权)。

下面的代码显示了如何注册一个 OAuth2AuthorizedClientManager@Bean 并将其与一个 OAuth2AuthorizedClientProvider 组合关联的示例,该组合提供uthorization_code``, ``refresh_token``, ``client_credentials``, and ``password授予类型的支持:

@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
		ClientRegistrationRepository clientRegistrationRepository,
		OAuth2AuthorizedClientRepository authorizedClientRepository) {
   
   

	OAuth2AuthorizedClientProvider authorizedClientProvider =
			OAuth2AuthorizedClientProviderBuilder.builder()
					.authorizationCode()
					.refreshToken()
					.clientCredentials()
					.password()
					.build();

	DefaultOAuth2AuthorizedClientManager authorizedClientManager =
			new DefaultOAuth2AuthorizedClientManager(
					clientRegistrationRepository, authorizedClientRepository);
	authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

	return authorizedClientManager;
}

Section Summary

Core Interfaces and Classes

本节介绍 SpringSecurity 提供的 OAuth2核心接口和类。

ClientRegistration

ClientRegistry 是用 OAuth 2.0或 OpenID Connect 1.0 Provider 注册的客户机的表示形式。

ClientRegistry 对象保存信息,如客户机 ID、客户机机密、授权授予类型、重定向 URI、作用域、授权 URI、令牌 URI 和其他详细信息。

ClientRegistry 及其属性定义如下:

public final class ClientRegistration {
   
   
	private String registrationId;	 //1
	private String clientId;	 //2
	private String clientSecret;	//3
	private ClientAuthenticationMethod clientAuthenticationMethod;	//4
	private AuthorizationGrantType authorizationGrantType;	//5
	private String redirectUri;	//6
	private Set<String> scopes;	//7
	private ProviderDetails providerDetails;
	private String clientName;	//8

	public class ProviderDetails {
   
   
		private String authorizationUri;	//9
		private String tokenUri;	//10
		private UserInfoEndpoint userInfoEndpoint;
		private String jwkSetUri;	//11
		private String issuerUri;	//12
        private Map<String, Object> configurationMetadata;//13

		public class UserInfoEndpoint {
   
   
			private String uri;	//14
            private AuthenticationMethod authenticationMethod;//15
			private String userNameAttributeName;	//16

		}
	}
}
  1. RegistrationId: 唯一标识 ClientRegistration的 ID。
  2. ClientId: 客户端标识符。
  3. clientSecret: 客户端密码。
  4. ClientAuthenticationMethod: 用于通过提供程序对客户端进行身份验证的方法。支持的值是 client_secret_basic, client_secret_post, private_key_jwt, client_secret_jwt and none (public clients).
  5. AuthorizationGrantType: OAuth 2.0授权框架定义了四种授权授权类型。支持的值包括 authorization_code, client_credentials, password 以及扩展授权类型 urn:ietf:params:oauth:grant-type:jwt-bearer。
  6. RedirectUri: 在最终用户对客户端进行身份验证和授权访问之后,Authorization Server 将最终用户的用户代理重定向到的客户端注册的重定向 URI。
  7. scopes: 客户端在授权请求流(如 openid、电子邮件或配置文件)中请求的作用域。
  8. ClientName: 用于客户端的描述性名称。该名称可用于某些场景,例如在自动生成的登录页面中显示客户端名称时。
  9. AuthorizationUri: 授权服务器的授权端点 URI。
  10. TokenUri: 授权服务器的令牌端点 URI。
  11. JwkSetUri: 用于从 Authorization Server 检索 JSON Web Key (JWK) Set 的 URI,其中包含用于验证 ID 令牌的 JSON Web Signature (JWS)和(可选) UserInfo Response 的单密钥。
  12. IsserUri: 返回 OpenID Connect 1.0提供程序或 OAuth 2.0 Authorization Server 的发行者标识符 URI。
  13. ConfigationMetadata: OpenID 提供程序配置信息。只有在配置了 Spring Boot 属性 Spring.security.oauth2.client.Provider. [ provision erId ] . isserUri 时,此信息才可用。
  14. (userInfoEndpoint) URI: 用于访问经过身份验证的最终用户的声明和属性的 UserInfo Endpoint URI。
  15. (userInfoEndpoint) enticationMethod: 向 UserInfo 端点发送访问令牌时使用的身份验证方法。支持的值是头、表单和查询。
  16. UserNameAttributeName: 在 UserInfo Response 中返回的引用最终用户的 Name 或 Identifier 的属性的名称。

通过使用 OpenID 连接提供程序的配置端点或授权服务器的元数据端点的发现,最初可以配置 ClientRegistration

ClientRegistration以这种方式为配置 ClientRegistration提供了方便的方法,如下所示:

ClientRegistration clientRegistration =
    ClientRegistrations.fromIssuerLocation("https://idp.example.com/issuer").build();

前面的代码查询按序列、 idp.example.com/issuer/.well-known/openid-configuration、 idp.example.com/.well-known/openid-configuration/issuer 和 idp.example.com/.well-known/oauth-authorization-server/issuer 进行,在第一个查询结束时返回200个响应。

作为替代方案,您可以使用 ClientRegistrations.forOidcIssuerLocation ()仅查询 OpenID 连接提供程序的 Configuration 端点。

ClientRegistrationRepository

ClientRegistrationRepository 充当 OAuth 2.0/OpenID Connect 1.0 ClientRegistration(s)的存储库。

客户端注册信息最终由关联的 AuthorizationServer 存储和拥有。此存储库提供了检索主客户端注册信息子集的能力,这些信息存储在 AuthorizationServer 中。

Spring Boot 自动配置绑定 spring.security.oauth2.client.registration.[registrationId] 的实例,然后在 ClientRegistrationRepository 中组合每个 ClientRegistration实例。

ClientRegistrationRepository 的默认实现是 InmemyClientRegistrationRepository。

自动配置还在 ApplicationContext 中将 ClientregistrationRepository 注册为一个@Bean,以便在应用程序需要的时候,它可以用于依赖注入。

下面的清单显示了一个示例:

@Controller
public class OAuth2ClientController {
   
   

	@Autowired
	private ClientRegistrationRepository clientRegistrationRepository;

	@GetMapping("/")
	public String index() {
   
   
		ClientRegistration oktaRegistration =
			this.clientRegistrationRepository.findByRegistrationId("okta");

		...

		return "index";
	}
}

OAuth2AuthorizedClient

OAuth2AuthorizedClient 是授权客户端的表示形式。当最终用户(资源所有者)授予客户端访问其受保护资源的权限时,客户端被认为是被授权的。

OAuth2AuthorizedClient 用于将 OAuth2AccessToken (和可选的 OAuth2RefreshToken)关联到 ClientRegistry (客户端)和资源所有者,后者是授予授权的主要最终用户。

OAuth2AuthorizedClientRepository and OAuth2AuthorizedClientService

OAuth2AuthorizedClientRepository 负责在 Web 请求之间保存 OAuth2AuthorizedClient (s) ,而 OAuth2AuthorizedClientService 的主要角色是在应用程序级别管理 OAuth2AuthorizedClient (s)。

从开发人员的角度来看,OAuth2AuthorizedClientRepository 或 OAuth2AuthorizedClientService 提供了查找与客户端关联的 OAuth2AccessToken 的能力,以便可以使用它来启动受保护的资源请求。

下面的清单显示了一个示例:

@Controller
public class OAuth2ClientController {
   
   

    @Autowired
    private OAuth2AuthorizedClientService authorizedClientService;

    @GetMapping("/")
    public String index(Authentication authentication) {
   
   
        OAuth2AuthorizedClient authorizedClient =
            this.authorizedClientService.loadAuthorizedClient("okta", authentication.getName());

        OAuth2AccessToken accessToken = authorizedClient.getAccessToken();

        ...

        return "index";
    }
}

OAuth2AuthorizedClientService 的默认实现是 InMemorial yOAuth2AuthorizedClientService,它在内存中存储 OAuth2AuthorizedClient 对象。

或者,您可以配置 JDBC 实现 JdbcOAuth2AuthorizedClientService 以在数据库中持久存储 OAuth2AuthorizedClient 实例。

JdbcOAuth2AuthorizedClientService 依赖于 OAuth 2.0 Client Schema.。

OAuth2AuthorizedClientManager and OAuth2AuthorizedClientProvider

OAuth2AuthorizedClientManager 负责 OAuth2AuthorizedClient (s)的全面管理。

主要职责包括:

  • 使用 OAuth2AuthorizedClientProvider 授权(或重新授权) OAuth2.0客户端。
  • 委托 OAuth2AuthorizedClient 的持久性,通常使用 OAuth2AuthorizedClientService 或 OAuth2AuthorizedClientRepository。
  • 当 OAuth 2.0客户端已经成功授权(或重新授权)时,委托给 OAuth2AuthorizationSuccess Handler。
  • 当 OAuth 2.0客户端无法授权(或重新授权)时,委托给 OAuth2AuthorizationFallureHandler。

OAuth2AuthorizedClientProvider 实现了授权(或重新授权) OAuth 2.0客户端的策略。实现通常实现授权授予类型,例如 authorization_code, client_credentials, and others.

OAuth2AuthorizedClientManager 的默认实现是 DefaultOAuth2AuthorizedClientManager,它与 OAuth2AuthorizedClientProvider 相关联,OAuth2AuthorizedClientProvider 可以使用基于委托的组合支持多种授权授权类型。可以使用 OAuth2AuthorizedClientProviderBuilder 配置和生成基于委托的组合。

下面的代码显示了如何配置和构建 OAuth2AuthorizedClientProvider 组合的示例,该组合提供对authorization_code, refresh_token, client_credentials, and password授予类型的支持:

@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
		ClientRegistrationRepository clientRegistrationRepository,
		OAuth2AuthorizedClientRepository authorizedClientRepository) {
   
   

	OAuth2AuthorizedClientProvider authorizedClientProvider =
			OAuth2AuthorizedClientProviderBuilder.builder()
					.authorizationCode()
					.refreshToken()
					.clientCredentials()
					.password()
					.build();

	DefaultOAuth2AuthorizedClientManager authorizedClientManager =
			new DefaultOAuth2AuthorizedClientManager(
					clientRegistrationRepository, authorizedClientRepository);
	authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

	return authorizedClientManager;
}

当授权尝试成功时,DefaultOAuth2AuthorizedClientManager 委托给 OAuth2AuthorizationSuccess Handler,该委托(默认情况下)通过 OAuth2AuthorizedClientRepository 保存 OAuth2AuthorizedClient。在重新授权失败的情况下(例如,刷新令牌不再有效) ,先前保存的 OAuth2AuthorizedClient 将通过 RemoveAuthorizedClientOAuthizationAuthorureHandler 从 OAuth2AuthorizedClientRepository 中删除。您可以通过 setAuthorizationSuccess Handler (OAuth2AuthorizationSuccess Handler)和 setAuthorizationfalureHandler (OAuth2AuthorizationfalureHandler)定制默认行为。

DefaultOAuth2AuthorizedClientManager 还与类型为 Function <OAuth2AuthorizeRequest,Map < String,Object > 的 contextAttributesMapper 相关联,后者负责将属性从 OAuth2AuthorizeRequest 映射到与 OAuth2AuthorizationContext 相关联的属性映射。当您需要为 OAuth2AuthorizedClientProvider 提供必需的(受支持的)属性时,例如 PasswordOAuth2AuthorizedClientProvider 要求资源所有者的用户名和密码在 OAuth2AuthorizationContext.getAttritribute ()中可用时,这会很有用。

下面的代码显示 contextAttributesMapper 的示例:

@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
		ClientRegistrationRepository clientRegistrationRepository,
		OAuth2AuthorizedClientRepository authorizedClientRepository) {
   
   

	OAuth2AuthorizedClientProvider authorizedClientProvider =
			OAuth2AuthorizedClientProviderBuilder.builder()
					.password()
					.refreshToken()
					.build();

	DefaultOAuth2AuthorizedClientManager authorizedClientManager =
			new DefaultOAuth2AuthorizedClientManager(
					clientRegistrationRepository, authorizedClientRepository);
	authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

	// Assuming the `username` and `password` are supplied as `HttpServletRequest` parameters,
	// map the `HttpServletRequest` parameters to `OAuth2AuthorizationContext.getAttributes()`
	authorizedClientManager.setContextAttributesMapper(contextAttributesMapper());

	return authorizedClientManager;
}

private Function<OAuth2AuthorizeRequest, Map<String, Object>> contextAttributesMapper() {
   
   
	return authorizeRequest -> {
   
   
		Map<String, Object> contextAttributes = Collections.emptyMap();
		HttpServletRequest servletRequest = authorizeRequest.getAttribute(HttpServletRequest.class.getName())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值