SpringSecurity开启注解权限
1.@EnableGlobalMethodSecurity 注解介绍
Spring Security默认是在配置类中使用URL进行拦截,禁用使用注解,想要开启注解使用则需要在配置类上加上 如下注解@EnableGlobalMethodSecurity
;
注解源码如下,共支持 prePostEnabled
, securedEnabled
,jsr250Enabled
,proxyTargetClass
四种参数;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({GlobalMethodSecuritySelector.class})
@EnableGlobalAuthentication
@Configuration
public @interface EnableGlobalMethodSecurity {
boolean prePostEnabled() default false;
boolean securedEnabled() default false;
boolean jsr250Enabled() default false;
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default 2147483647;
}
在Spring Security 2.0 开始 支持 JSR-250 注释 以及框架的原始@Secured
注释;
2.@Secured注解使用方式
需要在配置类加上 @EnableGlobalMethodSecurity(securedEnabled = true)
表明使用 @Secured
注解;
配置示例如下
/**
* @Author lsc
* <p> </p>
*/
@EnableWebSecurity// 开启springSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//.....略
}
注解使用示例如下,该注解只能使用在方法上面
@GetMapping("test/seu")
@Secured("ROLE_USER")
public String testSecurity() {
return "需要USER权限";
}
测试结果如下
@Secured 源码如下
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Secured {
String[] value();
}
该注解可以使用多个角色进行控制
@Secured({"ROLE_USER","ROLE_ADMIN"})
3.JSR-250注解
JSR-250 注释 使用需要在配置类上加上 @EnableGlobalMethodSecurity(jsr250Enabled = true)
; 配置示例如下:
@EnableWebSecurity// 开启springSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//.....略
}
- @RolesAllowed 允许的角色;
- @PermitAll 允许任何人访问
- @DenyAll 拒绝任何人访问
使用方式如下;
@RolesAllowed({"USER","ADMIN"}) 表示 只有 USER, ADMIN 角色权限才可以访问;
@GetMapping("test/allow")
@RolesAllowed({"USER","ADMIN"})
public String testAllow() {
return "需要权限";
}
@GetMapping("test/perm")
@PermitAll
public String testPerm() {
return "允许";
}
@GetMapping("test/deny")
@DenyAll
public String testDeny() {
return "拒绝";
}
4.prePostEnabled 规范
prePostEnabled 没有 原生的spring注解功能强大,所以其使用需要借助spring的EL表达式;
需要在配置类上加上 @EnableGlobalMethodSecurity(prePostEnabled = true)
注解
配置示例
@EnableWebSecurity// 开启springSecurity
//@EnableGlobalMethodSecurity(securedEnabled = true)
//@EnableGlobalMethodSecurity(jsr250Enabled = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//.....略
}
主要注解如下
- @PreAuthorize --方法之前验证授权
- @PostAuthorize --授权方法之后被执行
- @PostFilter --在方法执行之后执行,用于过滤集合;
- @PreFilter --在方法执行之前执行,用于过滤集合;
注解使用方式
@GetMapping("api/admin")
@PreAuthorize("hasRole('ADMIN')")
public String authAdmin() {
return "需要ADMIN权限";
}
@GetMapping("api/test")
@PreAuthorize("isAnonymous()")
public String authUser() {
return "匿名用户访问";
}
以及 hasAuthority 使用方式如下
@PreAuthorize("hasAuthority('ROLE_ADMIN')")
使用EL表达式判定方式如下
@GetMapping("api/has")
@PreAuthorize("#sysUser.username == 'admin' ")
public String hasPerm(SysUser sysUser) {
return "EL测试";
}
还可以使用 @P
注解获取参数
@GetMapping("api/sys")
@PreAuthorize("#c.username == authentication.principal ")
public String hasPerm2(@P("c")SysUser sysUser) {
return "EL测试";
}
如果是Spring Data的@Param
注解
@PreAuthorize("#n == authentication.principal")
public String hasPerm2(@Param("n")SysUser sysUser) {
return "EL测试";
}
5 权限被拒绝处理器
如果当用户访问自身不具有的权限接口时,springSecurity 会将异常信息传递给 AccessDeniedHandler ;我们只需要实现它即可;示例如下
/**
* @author lsc
* <p> 权限不足处理 </p>
*/
@Component
public class DenyHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
// 设置响应头
httpServletResponse.setContentType("application/json;charset=utf-8");
// 返回值
ResultPage result = ResultPage.error(CodeMsg.PERM_ERROR);
httpServletResponse.getWriter().write(JSON.toJSONString(result));
}
}
6 常见内置表达式
表达 | 描述 |
---|---|
hasRole([role]) |
如果当前主体具有指定角色,则返回true 。默认情况下,如果提供的角色不以“ROLE_”开头,则会添加该角色。这可以通过修改DefaultWebSecurityExpressionHandler 上的defaultRolePrefix 来自定义。 |
hasAnyRole([role1,role2]) |
如果当前主体具有任何提供的角色(以逗号分隔的字符串列表给出),则返回true 。默认情况下,如果提供的角色不以“ROLE_”开头,则会添加该角色。这可以通过修改DefaultWebSecurityExpressionHandler 上的defaultRolePrefix 来自定义。 |
hasAuthority([authority]) |
如果当前主体具有指定的权限,则返回true 。 |
hasAnyAuthority([authority1,authority2]) |
如果当前主体具有任何提供的权限(以逗号分隔的字符串列表给出),则返回true |
principal |
允许直接访问代表当前用户的主体对象 |
authentication |
允许直接访问从SecurityContext 获取的当前Authentication 对象 |
permitAll |
始终评估为true |
denyAll |
始终评估为false |
isAnonymous() |
如果当前主体是匿名用户,则返回true |
isRememberMe() |
如果当前主体是remember-me用户,则返回true |
isAuthenticated() |
如果用户不是匿名用户,则返回true |
isFullyAuthenticated() |
如果用户不是匿名用户或记住我用户,则返回true |
hasPermission(Object target, Object permission) |
如果用户有权访问给定权限的提供目标,则返回true 。例如,hasPermission(domainObject, 'read') |
hasPermission(Object targetId, String targetType, Object permission) |
如果用户有权访问给定权限的提供目标,则返回true 。例如,hasPermission(1, 'com.example.domain.Message', 'read') |
本套教程
- springSecurity入门(1)
- springSecurity配置(2)
- springSecurity登陆与退出json形式交互(3)
- springSecurity前后端分离集成jwt(4)
- SpringSecurity开启注解权限(4)
- springSecurity Cors 处理(6)
- 待续或者已更新
源码地址: 关注公众号知识追寻者,后台回复:springSecurity 获取