3 OAuth 2.0
OAuth 2.0是安全授权的工业标准协议,我们了解它需要理解下面的专用术语:
-
交互参与方:
- Client:需要访问
Resource Sever
受保护资源的应用; - Resource Owner :终端用户,
Client
通过终端用户进行不同类型的授权(Grant Type
); - Authorization Server:提供访问授权的应用,
Client
使用某种Grant Type
向Authorization Server
获取Access Token
; - Resource Sever:包含受保护资源的应用,
Client
使用Access Token
访问Resource Server
的受保护资源;
- Client:需要访问
-
授权类型 - Grant Type
- Authorization Code:让用户访问Client页面时,页面打向Authorization Server的登录页面,登录后显示授权访问页面,授权成功后Client即可获得Access Token访问Resource Server
- Password:通过提供提供用户名和密码获得Access Token,一般是给应用服务的客户端使用(IOS、Android、Web App)。
- Client Credentials:Client通过Client Id和Client Secret直接向Authorization Server请求Access Token;它主要用于非用户参与的应用,如后台服务。
-
Token
- Access Token:用来访问受保护资源的唯一令牌;
- Refresh Token:当Access Token失效时,我们可以使用Refresh Token来获取一个新的Access Token,它的时效性要远远大于Access Token
- JWT:JSON Web Token,它代表双方之间安全传输的信息;它使用数字签名,传输的信息可以被验证和信任。
3.1 OAuth 2.0 Authorization Server
新建应用,信息如下:
Group:top.wisely
Artifact:auth-server
Dependencies:Spring Security
、Spring Web Starter
、Spring Data JPA
、MySQL Driver
、Lombok
build.gradle
文件中的依赖如下:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'mysql:mysql-connector-java'
annotationProcessor 'org.projectlombok:lombok'
//...
}
Spring Security不提供OAuth 2.0 Authorization Server的功能,我们使用spring-security-oauth2-autoconfigure
来实现OAuth 2.0 Authorization Server的功能和配置。Spring Boot不提供spring-security-oauth2-autoconfigure
版本的维护,需指定它的版本。
implementation 'org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.2.X.RELEASE'
3.1.1 spring-security-oauth2-autoconfigure
提供的自动配置
spring-security-oauth2-autoconfigure
使用OAuth2AutoConfiguration
导入了关于Authorization Server配置OAuth2AuthorizationServerConfiguration
,他们通过AuthorizationServerProperties
用security.oauth2.authorization.*
来进行定制配置。OAuth2AuthorizationServerConfiguration
做了下面的配置:
AuthorizationServerConfigurerAdapter
:继承此类通过重载其方法对进行配置。configure(ClientDetailsServiceConfigurer clients)
:配置client的信息,可通过security.oauth2.client.*
来配置,只支持配置一个。configure(AuthorizationServerEndpointsConfigurer endpoints)
:配置Authorization Server端点的非安全特性。配置了TokenStore
、AccessTokenConverter
,若Grant Type为password
则需设置AuthenticationManager
。configure(AuthorizationServerSecurityConfigurer security)
:配置Authorization Server的安全性。tokenKeyAccess
:配置端点/oauth/token_key
的访问安全,提供JWT编码的Token;通过security.oauth2.authorization.tokenKeyAccess
来配置。checkTokenAccess
:配置端点/oauth/check_token
的访问安全,解码Access Token用来检查和确认生成的token;通过security.oauth2.authorization.checkTokenAccess
来配置。
- 导入
AuthorizationServerTokenServicesConfiguration
:配置JWT。TokenStore
:用来生成和获取token;自动配置了JwtTokenStore
的Bean;AccessTokenConverter
:将access token转换成不同的格式;自动配置了JwtAccessTokenConverter
转换成JWT格式。
3.1.2 获取用户配置
Authorization Server要获取终端用户,来获取用户相关信息。我们沿用上节的SysAuthority
、SysRole
、SysUser
、SysAuthorityRepository
、
SysRoleRepository
、SysUserRepository
、CusotmUserDetailsService
。我们的配置如下:
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
SysUserRepository sysUserRepository;
@Bean
protected UserDetailsService userDetailsService() {
return new CusotmUserDetailsService(sysUserRepository);
}
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
@Override //暴露authenticationManager Bean。
protected AuthenticationManager authenticationManager() throws Exception