Spring Boot整合Spring Security简记-O
new無语 转载请注明原创出处,谢谢!
ClientRegistration
ClientRegistration
表示OAuth 2.0或OpenID Connect 1.0客户端注册的信息 。
客户端注册包含客户端ID,客户端密码,授权授权类型,重定向URI,范围,授权URI,令牌URI和其他详细信息。
ClientRegistration
其属性定义如下:
public final class ClientRegistration {
private String registrationId;
private String clientId;
private String clientSecret;
private ClientAuthenticationMethod clientAuthenticationMethod;
private AuthorizationGrantType authorizationGrantType;
private String redirectUriTemplate;
private Set<String> scopes;
private ProviderDetails providerDetails;
private String clientName;
public class ProviderDetails {
private String authorizationUri;
private String tokenUri;
private UserInfoEndpoint userInfoEndpoint;
private String jwkSetUri;
public class UserInfoEndpoint {
private String uri;
private String userNameAttributeName;
}
}
}
-
registrationId
:ClientRegistration
唯一标识的ID 。 -
clientId
:客户端标识。 -
clientSecret
:客户端密码。 -
clientAuthenticationMethod
:用于向提供者验证客户端的方法。支持的值是basic 和post. -
authorizationGrantType
:OAuth 2.0授权框架定义了四种授权授权类型。支持的值是authorization_code和implicit。
oauth2根据使用场景不同,分成了4种模式
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
-
redirectUriTemplate
:客户端重定向URI,授权服务器将最终用户的用户代理重定向到最终用户对客户端进行身份验证和授权访问之后。默认的重定向URI模板是{baseUrl}/login/oauth2/code/{registrationId}
,它支持URI模板变量。 -
scopes
:授权请求流程期间客户端请求的范围,如openid,email, 或 profile。 -
clientName
:用于客户端的描述性名称。该名称可能会在某些情况下使用,例如在自动生成的登录页面中显示客户端的名称时。 -
authorizationUri
:授权服务器的授权端点URI。 -
tokenUri
:授权服务器的令牌端点URI。 -
jwkSetUri
:用于从授权服务器(包含用于验证ID令牌的JSON Web签名(JWS)和可选的UserInfo响应)的加密密钥中检索JSON Web密钥(JWK)的URI 。 -
(userInfoEndpoint)uri
:UserInfo端点URI,用于访问经过身份验证的最终用户的声明/属性。 -
userNameAttributeName
:UserInfo Response中返回的引用最终用户的名称或标识符的属性的名称。
Spring Boot 2.0属性映射
下表概述了Spring Boot 2.0 OAuth客户端属性到ClientRegistration
属性的映射。
Spring Boot 2.0 | ClientRegistration |
---|---|
spring.security.oauth2.client.registration.[registrationId] |
registrationId |
spring.security.oauth2.client.registration.[registrationId].client-id |
clientId |
spring.security.oauth2.client.registration.[registrationId].client-secret |
clientSecret |
spring.security.oauth2.client.registration.[registrationId].client-authentication-method |
clientAuthenticationMethod |
spring.security.oauth2.client.registration.[registrationId].authorization-grant-type |
authorizationGrantType |
spring.security.oauth2.client.registration.[registrationId].redirect-uri-template |
redirectUriTemplate |
spring.security.oauth2.client.registration.[registrationId].scope |
scopes |
spring.security.oauth2.client.registration.[registrationId].client-name |
clientName |
spring.security.oauth2.client.provider.[providerId].authorization-uri |
providerDetails.authorizationUri |
spring.security.oauth2.client.provider.[providerId].token-uri |
providerDetails.tokenUri |
spring.security.oauth2.client.provider.[providerId].jwk-set-uri |
providerDetails.jwkSetUri |
spring.security.oauth2.client.provider.[providerId].user-info-uri |
providerDetails.userInfoEndpoint.uri |
spring.security.oauth2.client.provider.[providerId].userNameAttribute |
providerDetails.userInfoEndpoint.userNameAttributeName |
ClientRegistrationRepository
ClientRegistrationRepository
用作于OAuth 2.0 / OpenID Connect 1.0 的ClientRegistration
存储。
Spring Boot 2.0自动配置将每个下面的属性绑定 到一个实例上,然后编写一个实例中的每个实例。spring.security.oauth2.client.registration.[registrationId]
ClientRegistrationClientRegistration
ClientRegistrationRepository
。
ClientRegistrationRepository
的默认实现是InMemoryClientRegistrationRepository
。
Spring Boot 2.0自动配置还会在ApplicationContext
注册ClientRegistrationRepository
作为@Bean
,这样它可用于依赖注入。
@Controller
public class MainController {
@Autowired
private ClientRegistrationRepository clientRegistrationRepository;
@RequestMapping("/")
public String index() {
ClientRegistration googleRegistration =
this.clientRegistrationRepository.findByRegistrationId("google");
...
return "index";
}
}
CommonOAuth2Provider
CommonOAuth2Provider
为众多知名供应商预先定义了一组默认的客户端属性:Google
,GitHub
,Facebook
和Okta
。
例如,authorization-uri
,token-uri
,和user-info-uri
不经常对供应商变更。因此,为了减少所需的配置,提供默认值是有意义的。
如前所述,当我们配置一个GitHub客户端时,只需要client-id
和client-secret
属性。
spring:
security:
oauth2:
client:
registration:
github:
client-id: github-client-id
client-secret: github-client-secret
客户端属性的自动默认功能在这里无缝工作,因为
registrationId
(github)匹配GITHUB
enum
(不区分大小写)CommonOAuth2Provider
。
对于可能需要指定不同的情况registrationId
,例如github-login
,仍然可以通过provider
配置属性来使用客户端属性的自动默认功能。
spring:
security:
oauth2:
client:
registration:
github-login:
provider: github
client-id: github-client-id
client-secret: github-client-secret
- 该
registrationId
设置为github-login。 - 该
provider
属性设置为github
,将利用客户端属性的自动默认设置CommonOAuth2Provider.GOOGLE.getBuilder()
。
配置自定义属性
有一些OAuth 2.0提供者支持多租户,这将导致每个租户(或子域)的不同协议端点。
例如,向Okta注册的OAuth客户端被分配到特定的子域,并拥有自己的协议端点。
对于这些情况,Spring Boot 2.0为配置自定义提供程序属性提供以下基本属性:。spring.security.oauth2.client.provider.[providerId]
。
spring:
security:
oauth2:
client:
registration:
okta:
client-id: okta-client-id
client-secret: okta-client-secret
provider:
okta:
authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize
token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token
user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo
user-name-attribute: sub
jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys
基本属性(
spring.security.oauth2.client.provider.okta
)允许自定义配置协议端点位置。
OAuth2AuthorizedClient / OAuth2AuthorizedClientService
OAuth2AuthorizedClient
表示授权客户端。客户端授权时被认为是最终用户(资源所有者)已经授予授权客户端访问受保护的资源。
OAuth2AuthorizedClientService
主要的作用是管理OAuth2AuthorizedClient
实例。
也可以在ApplicationContext
中注册OAuth2AuthorizedClientService
@Bean
,以便能够查找OAuth2AccessToken
与ClientRegistration
。
@Controller
public class MainController {
@Autowired
private OAuth2AuthorizedClientService authorizedClientService;
@RequestMapping("/userinfo")
public String userinfo(OAuth2AuthenticationToken authentication) {
// authentication.getAuthorizedClientRegistrationId() returns the
// registrationId of the Client that was authorized during the Login flow
OAuth2AuthorizedClient authorizedClient =
this.authorizedClientService.loadAuthorizedClient(
authentication.getAuthorizedClientRegistrationId(),
authentication.getName());
OAuth2AccessToken accessToken = authorizedClient.getAccessToken();
...
return "userinfo";
}
}