Spring Security oAuth2

Spring Security

Spring Security 是一个spring的安全框架

oAuth2

是一种授权协议,他的主要作用是为了提供认证和授权的标准

Access Token

客户端访问资源服务器的令牌,代表用户的授权

Refresh Token

刷新令牌,是用来实现安全令牌的时效机制,使通过安全令牌访问的资源更加安全

配置认证服务器

在云服务中一般有认证服务器和资源服务器,通常认证服务器用来获取用户的登录和授权信息,而资源服务器则用来校验具体的权限信息

认证服务器注解

@Configuration
@EnableAuthorizationServer

认证服务器继承类

认证服务器继承AuthorizationServerConfigurerAdapter
认证服务器通过客户端的id,密钥,客户端授权类型取得客户端授权范围

资源服务代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

/**
* @author admin
* @version v1.0.0
**/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

@Autowired
private BCryptPasswordEncoder passwordEncoder;

@Autowired
private AuthenticationManager authenticationManager;
// 增加 TokenStore 配置
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
// 增加 TokenStore 配置
.tokenStore(tokenStore());
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.checkTokenAccess("isAuthenticated()")
.allowFormAuthenticationForClients();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("client")
.secret(passwordEncoder.encode("secret"))
.authorizedGrantTypes("password", "refresh_token")
.scopes("backend")
.resourceIds("backend-resources")
.accessTokenValiditySeconds(60 * 60 * 24)
.refreshTokenValiditySeconds(60 * 60 * 24 * 30);
}
}

服务器安全配置

创建一个类继承 WebSecurityConfigurerAdapter 并添加相关注解(@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
)

服务器安全配置代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
* @author admin
* @version v1.0.0
**/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

@Bean
public BCryptPasswordEncoder passwordEncoder() {
// 设置默认的加密方式
return new BCryptPasswordEncoder();
}

@Bean
@Override
protected UserDetailsService userDetailsService() {
return new UserDetailsServiceImpl();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 使用自定义认证与授权
auth.userDetailsService(userDetailsService());
}

@Override
public void configure(WebSecurity web){
web.ignoring().antMatchers("/user/login").antMatchers("/user/logout");
/* .antMatchers("/oauth/authorize")
.antMatchers("/oauth/check_token");*/

}

/**
* 用于支持 password 模式
*
* @return
* @throws Exception
*/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
// 增加了授权访问配置,正常用户都可以注销
.antMatchers("/user/logout").hasAuthority("USER");
}
}

配置资源服务器

资源服务器则用来校验具体的权限信息

资源服务器注解

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)

资源服务器继承类

资源服务器继承ResourceServerConfigurerAdapter
资源服务器通声明自身资源ID和需要的角色权限

资源服务器代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/**").hasAuthority("USER");
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
// 配置资源 ID
resources.resourceId("backend-resources");
}
}

yml文件配置

1
2
3
4
5
6
7
8
9
10
security:
oauth2:
client:
client-id: client
client-secret: secret
access-token-uri: http://127.0.0.1:9001/oauth/token
user-authorization-uri: http://127.0.0.1:9001/oauth/authorize
id: client
resource:
token-info-uri: http://127.0.0.1:9001/oauth/check_token