Springboot整合SpringSecurity 07-方法访问权限控制
前面我们已经学会了SpringSecurity的权限访问控制。
但是之前的配置都是直接对请求路径的权限控制,SpringSecurity还提供了访问级别的权限控制。
必须具有相应的权限才能访问该方法。
本系列的按顺序写的,如果对于某些代码不清楚,请看下前面的几篇文章。
Springboot整合SpringSecurity 01-使用入门
Springboot整合SpringSecurity 02-使用自定义登陆页面
Springboot整合SpringSecurity 03-访问权限控制
Springboot整合SpringSecurity 04-启用登出logout功能
Springboot整合SpringSecurity 05-使用JDBC实现认证和授权
Springboot整合SpringSecurity 06-登陆扩展之自定义登陆验证逻辑
Springboot整合SpringSecurity 07-方法访问权限控制
1. 添加权限控制的方法。
/**
* @author flw
*/
public interface MethodSecureService {
/**
* 任何授权了的人都可以访问
* @return
*/
@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
String common();
/**
* ROLE_ADMIN权限访问
* @return
*/
@Secured("ROLE_ADMIN")
String admin();
/**
* ROLE_USER or ROLE_DBA 权限访问。
* @return
*/
@Secured({"ROLE_USER", "ROLE_DBA"})
String user();
/**
* 任何授权了的人都可以访问
* @return
*/
@PreAuthorize("isAuthenticated()")
String common2();
/**
* ROLE_ADMIN权限访问
* @return
*/
@PreAuthorize("hasAuthority('ROLE_ADMIN')")
String admin2();
/**
* ROLE_USER && ROLE_DBA 权限访问。
* @return
*/
@PreAuthorize("hasAuthority('ROLE_USER') && hasAuthority('ROLE_DBA')")
String user2();
}
上面我们提供了6个接口,分别有@Secure和@PreAuthorize注解实现的,这两种功能上其实没有太大区别。
注意:@Secured里面添加多个权限之间是或者的关系,就是有一个权限就可以。
@PreAuthorize后面我们可以用Spring-EL表达式实现且的关系如上面的user2()接口。
@PreAuthorize更多的指定权限的方法可以到SecurityExpressionRoot里面查找。
@PreAuthorize("hasAuthority('ROLE_USER')")
public interface MethodSecureService2 {
/**
* 类级别的控制
* @return
*/
String user3();
}
这些注解处理在方法上面使用外,还可以直接在类上面使用,表示整个类的方法权限控制。
@Service
public class MethodSecureServiceImpl implements MethodSecureService {
@Override
public String common() {
return "common";
}
@Override
public String admin() {
return "admin";
}
@Override
public String user() {
return "user";
}
@Override
public String common2() {
return "common2";
}
@Override
public String admin2() {
return "admin2";
}
@Override
public String user2() {
return "user2";
}
}
@Service
public class MethodSecureService2Impl implements MethodSecureService2 {
@Override
public String user3() {
return "user3";
}
}
上面是两个接口的实现类,很简单就是返回一个字符串。
2.添加请求的接口
@RequestMapping("method")
@RestController
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class MethodSecureController {
@Autowired
private MethodSecureService methodSecureService;
@Autowired
private MethodSecureService2 methodSecureService2;
@GetMapping("common")
public String common() {
return methodSecureService.common();
}
@GetMapping("admin")
public String admin() {
return methodSecureService.admin();
}
@GetMapping("user")
public String user() {
return methodSecureService.user();
}
@GetMapping("common2")
public String common2() {
return methodSecureService.common2();
}
@GetMapping("admin2")
public String admin2() {
return methodSecureService.admin2();
}
@GetMapping("user2")
public String user2() {
return methodSecureService.user2();
}
@GetMapping("user3")
public String user3() {
return methodSecureService2.user3();
}
}
注意:
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
要开启方法级别的权限控制,需要提供上面这个注解,一般我们写在Springboot启动类上面。这里为了方便,我就直接写在这个Controller里面了。
其中securedEnabled=true是如果使用的@Secure注解的话需要加上的。
prePostEnabled = true是如果使用@PreAuthorize注解的话需要加上的。
3. 启动项目开始测试。
首先我们使用user:userpwd登陆
http://localhost:10022/security/login
然后访问
http://localhost:10022/security/method/user
发现可以访问成功,
说明:@Secure后面多个权限直接的关系是OR的关系,有一个就可以实现。
接着我们访问
http://localhost:10022/security/method/user2
发现403错误。
然后我们使用dba:dbapwd的账号密码登陆再去访问上面的user2接口。
发现可以访问。
说明:@PreAuthorize可以通过&&的Spring-EL语法实现AND的关系,必须两个权限同时满足才能访问。
其他的几个接口可以自行测试,这里就不一一介绍了。