Spring Security-31-授权的使用

之前的部分都是说的是认证的流程,并没有详细的使用过权限,本文来看一下如何做权限控制.

其实在我们之前的使用中,已经用到了一部分的权限控制,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.authorizeRequests()
// 匹配的是登录页的话放行
.antMatchers(
SecurityConstants.DEFAULT_UNAUTHENTICATION_URL,
SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_MOBILE,
SecurityConstants.DEFAULT_VALIDATE_CODE_URL_PREFIX + "/*",
securityProperties.getBrowser().getLoginPage(),
SecurityConstants.DEFAULT_SIGN_UP_URL,
securityProperties.getBrowser().getSignUpPage(),
SecurityConstants.GET_SOCIAL_USER_URL,
securityProperties.getBrowser().getSession().getSessionInvalidUrl(),
"/user/register"
)
.permitAll()
// 授权请求. anyRequest 就表示所有的请求都需要权限认证
.anyRequest().authenticated()

这里就是针对请求做权限的控制, .antMatchers() 方法用来匹配URL, 然后还有面的 .permitAll() 就是表示不需要任何权限

最后 anyRequest() 就是所有的请求,authenticated() 就表示需要登录之后才能访问,这些就是一些简单的权限控制,下面来详细的看一下,还有哪些使用方式

权限控制

在实际的开发环境中,权限一般就是RBAC模型,就是用户去绑定角色,角色去绑定权限,这样的处理方式,下面来看一下如何去针对用户的角色去控制权限

举个例子,比如一个人员列表的接口 /users ,这个接口需要角色是管理员的用户才能访问, 那么代码中的配置如下:

1
.antMatchers("/users").hasRole("ADMIN")

这里首先是匹配 /users 这个接口, hasRole() 就表示访问这个接口需要的角色,然后参数是 ADMIN ,就是管理员角色,那这个角色是从哪里来呢?

之前我们在 UserDetailsService 里面有这样一段代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
log.info("进行用户认证...");
User user = userService.findUserByPhoneNo(username);

if (user == null) {
throw new UsernameNotFoundException("用户不存在");
}
// 查询出来,返回去
return new org.springframework.security.core.userdetails.User(
user.getId().toString(),
user.getPassword(),
user.getEnable(),
true,
true,
!user.getLocked(),
AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_USER"));
}

最后返回的 User 对象中,最后一个参数就是用户的权限和角色, 角色的前缀是 ROLE_ 这个是写死的, 我们上面的请求是要 ADMIN 的角色,所以这里需要返回的一个角色是 ROLE_ADMIN 代码如下:

1
2
3
4
5
6
7
8
9
return new org.springframework.security.core.userdetails.User(
user.getId().toString(),
user.getPassword(),
user.getEnable(),
true,
true,
!user.getLocked(),
AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_USER,ROLE_ADMIN"));
}

匹配restful Api

在restful的请求中,可能请求路径是一样的,但是请求的方式是不一样的,比如GET POST,那如何区分这种请求呢,如下:

1
.antMatchers(HttpMethod.GET, "/users").hasRole("ADMIN")

这里就是表示是 GET /users 这个请求是需要 ADMIN 角色的

授权表达式

Spring Security 提供了一下几种方法

表达式 说明
permitAll 永远返回true
denyAll 永远返回false
anonymous 当前用户是anonymous时返回true
rememberMe 当前用户是rememberMe用户时返回true
authenticated 当前用户不是anonymous时返回true
fullAuthenticated 当前用户既不是anonymous也不是rememberMe用户时返回true
hasRole(role) 用户拥有指定的角色权限时返回true
hasAnyRole([role1,role2) 用户拥有任意一个指定的角色权限时返回true
hasAuthority(authority) 用户拥有指定的权限时返回true
hasAnyAuthority(authority1, authority2]) 用户拥有任意个指定的权限时返回true
haslpAddress( ‘192.168.1.0/24’ ) 请求发送的lp匹配时返回true

这里有一个是 anonymous 这个之后再做说明

每一个表达式都对应了 .antMatchers() 后面的一个方法 ,比如:

1
2
3
.antMatchers("/url").permitAll()
.antMatchers("/url").denyAll()
.antMatchers("/url").hasRole("ADMIN")

组合使用

举个例子,比如某个接口指定ip的管理员用户才能访问,这里就用到了两个表达式,那么如何去组合使用,如下:

1
2
.antMatchers("/url").access("haslpAddress( 
'192.168.1.0/24') and hasRole('ADMIN')")

这里是使用 access() 方法去组合自己的表达式

关于授权的部分就先介绍到这里