spring security OAuth2 支持

在spring security 中对OAuth2的支持主要是对 OAuth2协议4个角色中对,客户端 (Client) 、资源服务器 (Resource Server) 的集成支持。

OAuth2 Client

Authorization Code Grant 流程

对流程稍加改造后,可以实现通过第三方服务授权

user agent:resource owner的代理,必须能执行url重定向,一般是浏览器,app

client:OAUTH2.O Client,用来获取resource owner授权的token

authorization server:授权服务器,用于验证client,获取resource owner授权及签发token

  1. 用户通过user agent 发送登录请求
  2. client 响应提供授权服务的选项,
  3. 用户选自己适合的授权服务选项
  4. client 响应重定向到authorization server rul ,携带client标识,凭据,授权类型及resource owner 授权后返回client url
  5. 重定向到authorization server
  6. authorization server 请求授权
  7. 用户通过user agent 授权
  8. authorization server 响应重定向client url,  携带resource owner 授权码
  9. user agent 重定向到client,
  10. client 请求authorization server 签发token
  11. authorization server 签发token
  12. 返回token到user agent

登录过虑器

HttpSecurity.oauth2login() 要求用户通过OAuth2登录,在OpenID Connect 1.0 中提供了一个名为id_token的特殊令牌,旨在为OAuth2客户端提供执行用户身份验证和登录用户的能力。

DefaultLoginPageGeneratingFilter:是在配置SecurityFilterChain 是通过HttpSecurity.oauth2Login()配置的一个Security Filter,其主要作用是

  1. 自动生成oauth2 login 页面,显示配置的ClientRegistration
  2. 利用身份验证者管理器进行身份验证者并生成授权客户端(OAuth2AuthorizedClient)
  3. 授权客户端大保存到OAuth2AuthorizedClientRepository and OAuth2AuthorizedClientService中

ClientRegistration 是代表client 中注册的OAuth 2.0 or OpenID Connect 1.0的提供者,包含client id, client secret, authorization grant type, redirect URI, scope(s), authorization URI, token URI, and other details

ClientRegistrationRepository 用于存储和提供ClientRegistration对象。默认实现类是InMemoryClientRegistrationRepository

OAuth2AuthorizedClient  代表一个已授权客户端。当终端用户(资源所有者)授予客户端访问其受保护资源的授权时,客户端被认为是被授权的

OAuth2AuthorizedClientRepository and OAuth2AuthorizedClientService  用于存储和提供OAuth2AuthorizedClient 对象,OAuth2AuthorizedClientRepository 是一个管理web 请求级的OAuth2AuthorizedClient 对象(一般非web中请求时获取不token),OAuth2AuthorizedClientService  是管理应用级的OAuth2AuthorizedClient

OAuth2AuthorizedClientManager : OAuth2AuthorizedClientManager 的实现类全面管理授权客户端OAuth2AuthorizedClient),可以用于获取访问OAuth2 Resource Server的内容token,主要作用:

  • 通过OAuth2AuthorizedClientProvider的实现类获取授权。 
  • 管理OAuth2AuthorizedClient的持久性,通常使用OAuth2AuthorizedClientService或OAuth2AuthorizedClientRepository。

OAuth2AuthorizedClientProvider: 用于获取授权客户端(OAuth2AuthorizedClient)

授权重定向过虑器

OAuth2AuthorizationRequestRedirectFilter:此Security Filter,主要用是:

  1. 利用OAuth2AuthorizationRequestResolver从web请求中的ClientRegistration 创建一个OAuth2AuthorizationRequest对象,将根据此对象返回重定向authorization url(授权url) 到user agent。
  2. 利用AuthorizationRequestRepository保存删除OAuth2AuthorizationRequest 

OAuth2AuthorizationRequestResolver:从web请求中的ClientRegistration创建一个OAuth2AuthorizationRequest,默认实现类是DefaultOAuth2AuthorizationRequestResolver,可以创建新的实现类来自定义OAuth2AuthorizationRequest,例如添加新参数等

AuthorizationRequestRepository负责从发起授权请求到接收授权响应(回调)期间OAuth2AuthorizationRequest的持久化。默认实现类是OAuth2AuthorizationRequest,是将OAuth2AuthorizationRequest 保存在AuthorizationRequestRepository。

token 获取(身份验证者)

获取token,基本上spring security 身份验证一致,登录过虑器使用身份验证者管理器获取身份验证者OAuth2LoginAuthenticationProvider

OAuth2LoginAuthenticationProvider:有两作用:

  1. 利用OAuth2AuthorizationCodeAuthenticationProvider获取token,OAuth2AuthorizationCodeAuthenticationProvider 也是利用OAuth2AccessTokenResponseClient 获取token
  2. 利用OAuth2UserService 获取用户信息,并利用GrantedAuthoritiesMapper 将用用户授权信息转换为 GrantedAuthority 列表对象

OAuth2AccessTokenResponseClient:负责使用授权凭证交换token,目前还是使用RestTemplate 来与Authorization Server 交互,可以通过OAuth2AccessTokenResponseClient 配置使用的RestTemplate,

  • 其为Authorization Code类型授权的实现类是DefaultAuthorizationCodeTokenResponseClient 负现将Authorization Code 交换成Access Token,DefaultAuthorizationCodeTokenResponseClient来实现在交换请求前后实实现一些个性需求,
  • 其为refresh_token类型授权的实现类是DefaultRefreshTokenTokenResponseClient,
  • 其为client_credentials类型授权的实现类是DefaultClientCredentialsTokenResponseClient,负现将 Client Credentials 交换成Access Token

OAuth2UserService:从UserInfo Endpoint 获取用户信息,为OAuth 2.0默认实现类是DefaultOAuth2UserService,为OpenID Connect 1.0默认实现类是OidcUserService,

GrantedAuthritiesMapper:将用用户信息转换为 GrantedAuthority 列表对象,转换用户还可以使用

客户端认证(Client Authentication Support)

使用HTTP Basic(client_secret_basic)、client credentials(client_secret_post) 的客户端身份验证是开箱即用的,不需要定制就可以启用它。默认实现由DefaultOAuth2TokenRequestHeadersConverter提供。

JWT Bearer 客户端身份验证的默认实现类是NimbusJwtClientAuthenticationParametersConverter,是在client_assertion参数中添加签名的Token。

NimbusJwtClientAuthenticationParametersConverter生成的JWT默认包含iss、sub、aud、jti、iat和exp声明。可以通过NimbusJwtClientAuthenticationParameter 的setJwtClientAssertionCustomizer() 方法添加定制的headers和claims

oauth2 Client提供了许多自定义OAuth 2.0 Login的配置选项。主要配置选项被分组到它们对应的协议端点中

@Configuration
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {

	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.oauth2Login(oauth2 -> oauth2
			    .authorizationEndpoint(authorization -> authorization
			            ...
			    )
			    .redirectionEndpoint(redirection -> redirection
			            ...
			    )
			    .tokenEndpoint(token -> token
			            ...
			    )
			    .userInfoEndpoint(userInfo -> userInfo
			            ...
			    )
			);
		return http.build();
	}
}

spring boot OAuth2 支持多种授权方式,Client Credentials,Password Credentials 等,相对Authorization Code Grant 流程简单一些。

OAuth2 Resource Server

在resource Server 上的身份验证(Authentication)基本上与Spring Security身份验证机制一样。

  1. 过虑器丛web请求中读取Bearer Token并创建BearerTokenAuthenticationToken,然后传递到身份验证管理器(AuthenticationManager)
  2. 身份验证管理器调用身份验证者(JwtAuthenticationProvider)
  3. 身份验证者使用使用JwtDecoder对Jwt进行解码、验证和验证,并使用JwtAuthenticationProvider使用JwtAuthenticationConverter将Jwt转换为授予权限(Authority)的集合
  4. 如果身份验证通过,返回JwtAuthenticationToken,如果失败走异常处理调用AuthenticationEntryPoint

JwtDecoder 

在resource Server JwtDecoder 是验证token的关键,有很多相关的配置:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://idp.example.com
          jws-algorithms: RS512
          jwk-set-uri: https://idp.example.com/.well-known/jwks.json
          audiences: https://my-resource-server.example.com

issuer-uri:指定授权服务器,使用默认值,需要的最少配置,其它可以不配置

jwk-set-uri:指定jwk的位置

audiences:默认会验证token payload 中的iss 是否与issuer-uri相同,这个属性还验证aud 是否与audiences值相同

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          public-key-location: classpath:my-key.pub

public-key-location:指定非对称加密公钥

Authorization Server

OAuth2AuthorizationServerConfiguration是一个@Configuration,它为OAuth2授权服务器提供最小的默认配置。可以自定义安全配置。

提供了如下的配置选项

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

	authorizationServerConfigurer
		.registeredClientRepository(registeredClientRepository) 
		.authorizationService(authorizationService) 
		.authorizationConsentService(authorizationConsentService)   
		.authorizationServerSettings(authorizationServerSettings) 
		.tokenGenerator(tokenGenerator) 
		.clientAuthentication(clientAuthentication -> { })  
		.authorizationEndpoint(authorizationEndpoint -> { })    
		.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint -> { })    
		.deviceVerificationEndpoint(deviceVerificationEndpoint -> { })  
		.tokenEndpoint(tokenEndpoint -> { })    
		.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint -> { })  
		.tokenRevocationEndpoint(tokenRevocationEndpoint -> { })    
		.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint -> { })    
		.oidc(oidc -> oidc
			.providerConfigurationEndpoint(providerConfigurationEndpoint -> { })    
			.logoutEndpoint(logoutEndpoint -> { })  
			.userInfoEndpoint(userInfoEndpoint -> { })  
			.clientRegistrationEndpoint(clientRegistrationEndpoint -> { })  
		);

	return http.build();
}

AuthorizationServerSettings:它指定了协议端点的URI以及颁发者标识符。协议端点的默认URI如下:

public final class AuthorizationServerSettings extends AbstractSettings {

	...

	public static Builder builder() {
		return new Builder()
			.authorizationEndpoint("/oauth2/authorize")
			.deviceAuthorizationEndpoint("/oauth2/device_authorization")
			.deviceVerificationEndpoint("/oauth2/device_verification")
			.tokenEndpoint("/oauth2/token")
			.tokenIntrospectionEndpoint("/oauth2/introspect")
			.tokenRevocationEndpoint("/oauth2/revoke")
			.jwkSetEndpoint("/oauth2/jwks")
			.oidcLogoutEndpoint("/connect/logout")
			.oidcUserInfoEndpoint("/userinfo")
			.oidcClientRegistrationEndpoint("/connect/register");
	}

	...

}

OAuth2ClientAuthenticationConfigurer:通过配置OAuth2ClientAuthenticationFilter, 提供了自定义OAuth2客户端身份验证的功能。

OAuth2ClientAuthenticationFilter是处理客户端身份验证请求的Filter

JwtClientAssertionDecoderFactory:提供一个OAuth2TokenValidator<Jwt>用于用来验证Jwt claims,通过向setJwtValidatorFactory()提供自定义Function<RegisteredClient, OAuth2TokenValidator<Jwt>>,覆盖默认验证Jwt claims能力

X509ClientCertificateAuthenticationProviderv:OAuth2客户端身份验证期间使用ClientAuthenticationMethod.TLS_CLIENT_AUTH or ClientAuthenticationMethod.SELF_SIGNED_TLS_CLIENT_AUTH 方法时用于验证客户端x509证书链。它还由“证书验证器”组成,用于在TLS握手成功完成后验证客户端x509证书的内容。

RegisteredClient:是向授权服务器注册的客户端。客户端必须先向授权服务器注册,然后才能启动授权授予流(如authorization_code或client_credentials),在客户端注册期间,客户端被分配一个唯一的客户端标识符(clientId),(可选地)一个客户端秘密(clientSecret)(取决于客户端类型),以及与其唯一客户端标识符相关联的元数据。客户机的元数据可以是面向人的显示字符串(如客户机名称),也可以是特定于协议流的项(如有效重定向uri列表)。

RegisteredClientRepository:用于存储RegisteredClient,RegisteredClientRepository提供的实现是InMemoryRegisteredClientRepository和jdbcreregisteredclientrepository。

OAuth2Authorization:OAuth2Authorization是OAuth2授权的表示形式,它保存与资源所有者授予客户端的授权相关的状态,根据不同的授权类型包含不同的OAuth2Token的实现类 

OAuth2AuthorizationService:用于存储OAuth2Authorization,OAuth2AuthorizationService提供的实现是InMemoryOAuth2AuthorizationService 和JdbcOAuth2AuthorizationService。

OAuth2AuthorizationConsent:是来自OAuth2授权请求流的授权“同意”(决策)的表示形式——例如,authorization_code授予,它保存资源所有者授予客户端的权限。

OAuth2AuthorizationConsentService:用于存储OAuth2AuthorizationConsent,OAuth2AuthorizationConsentService提供的实现是InMemoryOAuth2AuthorizationConsentService 和JdbcOAuth2AuthorizationConsentService

OAuth2TokenContext:是一个context对象,它包含与OAuth2Token相关的信息,并由OAuth2TokenGenerator和OAuth2TokenCustomizer使用

OAuth2TokenGenerator:负责从提供的OAuth2TokenContext中包含的信息生成OAuth2Token。

OAuth2TokenCustomizer:OAuth2TokenCustomizer提供了自定义OAuth2Token属性的能力,OAuth2TokenGenerator使用它生成OAuth2Token自定义其属性。

SessionRegistry:如果启用OpenID Connect 1.0,则使用SessionRegistry实例跟踪经过验证的会话。OAuth2授权端点关联的SessionAuthenticationStrategy的默认实现类使用SessionRegistry 跟踪身份验证的会话。SessionRegistryImpl 是其默认实现类

  • 29
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值