我们以spring cloud security OAuth2.0+JWT为案例分析如何搭建自己的用户认证中心(UAA: User Account and Authentication)。spring cloud security的安全体系庞大而复杂。先看看关键的依赖包的关系:
以上是搭建一个UAA所需要最核心的jar包,我等凡人实在无法在有限的时间内阅读完所有spring security的源代码。只能通过关键的过程看看最核心的功能。
基本配置
基于以上我们看到的依赖链,我们只需要引入很少的jar包就可以搭建起来UAA。
pom.xml配置:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<!-- spring-security-jwt不在parent版本管理中,需要配置版本号 -->
<version>1.0.10.RELEASE</version>
</dependency>
application.yml配置
security:
oauth2:
authorization:
token-key-access: permitAll()
jwt:
key-store: classpath:jwt-rsa.jks
key-store-password: passwd
key-alias: mytest
配置过程分析
spring cloud security oauth2的自动配置在spring boot2.0已经移动到spring-security-oauth2-autoconfigure.jar中。该工程导入了OAuth2AutoConfiguration自动配置。
OAuth2AutoConfiguration的引入链为:
OAuth2AutoConfiguration
=> OAuth2ClientProperties
=> OAuth2AuthorizationServerConfiguration
=> AuthorizationServerTokenServicesConfiguration
=> AuthorizationServerProperties
=> OAuth2ResourceServerConfiguration
=> ResourceServerTokenServicesConfiguration
=> OAuth2MethodSecurityConfiguration
=> OAuth2RestOperationsConfiguration
我们自建UAA需要通过@EnableAuthorizationServer引入认证中心的相关配置。
@EnableAuthorizationServer的引入链为
@EnableAuthorizationServer
=> AuthorizationServerEndpointsConfiguration
=> TokenKeyEndpointRegistrar
=> AuthorizationServerSecurityConfiguration
=> ClientDetailsServiceConfiguration
=> AuthorizationServerEndpointsConfiguration
我们的认证中心自身也需要得到安全管理,spring-boot-autoconfigure.jar通过WebSecurityEnablerConfiguration导入了@EnableWebSecurity。但我们通常需要重载这个注解。
@EnableWebSecurity的引入链为:
@EnableWebSecurity
=> WebSecurityConfiguration
=> SpringWebMvcImportSelector
=> WebMvcSecurityConfiguration
=> OAuth2ImportSelector
OAuth2AutoConfiguration为我们自动引入了AuthorizationServerTokenServicesConfiguration和ResourceServerTokenServicesConfiguration。这两个java config根据配置文件初始化不同的TokenService。由于我们配置了security.oauth2.authorization.jwt,所以初始化了JwkTokenStore。
security.oauth2.authorization.jwt.key-store配置的是在classpath下的一个RSA密钥文件。
我们需要通过keytool生成keystore:
keytool -genkeypair -alias mytest
-keyalg RSA
-keypass passwd
-keystore jwt-rsa.jks
-storepass passwd
ResourceServerTokenServicesConfiguration的配置在不同环境下有不同的初始化方案。
我们实际开发过程中只需要根据需要配置security.oauth2.resource.jwt参数即可。
测试OAuth2.0接口:
客户端模式
curl first-client:se@localhost:8100/oauth/token -dgrant_type=client_credentials -dscope=any
账号密码模式
curl first-client:se@localhost:8100/oauth/token -dgrant_type=password -dscope=any -d username=test -d password=test
通过refresh_token刷新access_token
curl first-client:se@localhost:8100/oauth/token -d grant_type=refresh_token -dscope=any -d refresh_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9。。。
获取JWK
curl first-client:se@localhost:8100/oauth/token_key
请求资源
curl -H "Authorization: $TOKEN" http://localhost:8101/whoami
参考
Using JWT with Spring Security OAuth: https://www.baeldung.com/spring-security-oauth-jwt