zoukankan      html  css  js  c++  java
  • 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 获取

  • 相关阅读:
    插入排序
    dojo树的节点添加链接的例子
    Discuz 3x 配置问题
    mysql_connect() 不支持 请检查 mysql 模块是否正确加载
    IIS访问php页面问题,报告404错误
    Map使用操作系统内存的情况
    IT级别
    java类型和mysql类型的转换
    C++析构函数的自动调用问题
    c++中虚函数
  • 原文地址:https://www.cnblogs.com/zszxz/p/14576156.html
Copyright © 2011-2022 走看看