Spring Security动态权限控制居然如此简单 | Java Debug 笔记

标签: spring security 控制 | 发表时间:2021-05-12 16:03 | 作者:码农小胖哥
出处:https://juejin.cn/backend

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接

之前在动态权限控制的教程中,我们通过自定义 FilterInvocationSecurityMetadataSourceAccessDecisionManager 两个接口实现了动态权限控制。这里需要我们做的事情比较多,有一定的学习成本。今天来介绍一种更加简单和容易理解的方法实现动态权限控制。

基于表达式的访问控制

   httpSecurity.authorizeRequests()
    .anyRequest()
    .access("hasRole('admin')")
复制代码

这种方式不用多说了吧,我们配置了表达式 hasRole('admin')后,Spring Security会调用 SecurityExpressionRoothasRole(String role)方法来判断当前用户是否持有角色 admin,进而作出是否放行的决策。这种方式除了可以静态的权限控制之外还能够动态的权限控制。

基于Bean的访问控制表达式

Spring Security扩展了对表达式进行了扩展,支持引用任何公开的 Spring Bean,假如我们有一个实现下列接口的 Spring Bean:

   /**
 * 角色检查器接口.
 *
 * @author n1
 * @since 2021 /4/6 16:28
 */
public interface RoleChecker extends InitializingBean {

    /**
     * Check boolean.
     *
     * @param authentication the authentication
     * @param request        the request
     * @return the boolean
     */
    boolean check(Authentication authentication, HttpServletRequest request);
}
复制代码

基于JDBC的角色检查,最好这里做个缓存:

   /**
 * 基于jdbc的角色检查 最好这里做个缓存
 * @author n1
 * @since 2021/4/6 16:43
 */
public class JdbcRoleChecker implements RoleChecker {
    // 系统集合的抽象实现,这里你可以采用更加合理更加效率的方式
    private Supplier> supplier;


    @Override
    public boolean check(Authentication authentication, HttpServletRequest request) {
        Collection authorities = authentication.getAuthorities();

       // 当前用户的角色集合
        System.out.println("authorities = " + authorities);
        //todo 这里自行实现比对逻辑
       //   supplier.get().stream().filter(matcher -> matcher.matches(request));
       // true false 为是否放行
        return true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(supplier.get(), "function must not be null");
    } 
}
复制代码

我们就可以这样配置 HttpSecurity

   httpSecurity.authorizeRequests()
    .anyRequest()
    .access("@roleChecker.check(authentication,request)")
复制代码

通过 RoleChecker中的 Authentication我们可以获得当前用户的信息,尤其是权限集。通过 HttpServletRequest我们可以获得当前请求的 URI。该 URI在系统中的权限集和用户的权限集进行交集判断就能作出正确的访问决策。

路径参数

有些时候我们的访问 URI中还包含了路径参数,例如 /foo/{id}。我们也可以通过基于Bean的访问控制表达式结合具体的 id值来控制。这时应该这么写:

   /**
 * 角色检查器接口.
 *
 * @author n1
 * @since 2021 /4/6 16:28
 */
public interface RoleChecker extends InitializingBean {

    /**
     * Check boolean.
     *
     * @param authentication the authentication
     * @param request        the request
     * @return the boolean
     */
    boolean check(Authentication authentication, String id);
}
复制代码

对应的配置为:

   httpSecurity.authorizeRequests()
    .antMatchers("/foo/{id}/**")
    .access("@roleChecker.check(authentication,#id)")
复制代码

这样当 /foo/123请求被拦截后, 123就会赋值给 check方法中的 id处理。

总结

这种表达式的动态权限控制比之前的方式更加容易掌握和理解。但是它也有它的局限性,比如表达式中的方法中的参数类型比较单一。而通过 FilterInvocationSecurityMetadataSource的方式则更加强大可以自定义一些访问决策,适合更加复杂的场景。我是: 码农小胖哥,多多关注,分享更多原创编程干货。

相关 [spring security 控制] 推荐:

spring security 3.1.0 控制用户重复登陆

- - CSDN博客架构设计推荐文章
通过配置我们可以实现两个需求 1、限制不允许第二个用户登录,2、第二个登陆用户踢掉前一个登陆用户 . 假设你的spring架构已经可以使用了(其他的主要功能完成),需要增加登录限制功能. 注:这里只写配置不写原理(不懂的就问度娘),其实个人认为先配置好跑起来再研究下原理最好了. 通过sessionRegistry可以获取系统当前在线人数和登录用户信息.

Spring Security动态权限控制居然如此简单 | Java Debug 笔记

- - 掘金 后端
本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看. 之前在动态权限控制的教程中,我们通过自定义 FilterInvocationSecurityMetadataSource和 AccessDecisionManager 两个接口实现了动态权限控制. 这里需要我们做的事情比较多,有一定的学习成本.

cxf + spring 的WS Security示例

- - RSS - IT博客云
WSPasswordCallback的 passwordType属性和 password属性都为null,你只能获得用户名(identifier),一般这里的逻辑是使用这个用户名到数据库中查询其密码,然后再设置到 password属性,WSS4J会自动比较客户端传来的值和你设置的这个值. 你可能会问为什么这里CXF不把客户端提交的密码传入让我们在 ServerPasswordCallbackHandler中比较呢.

Spring Security 实战干货:图解Spring Security中的Servlet过滤器体系

- - SegmentFault 最新的文章
我在 Spring Security 实战干货:内置 Filter 全解析对 Spring Security的内置过滤器进行了罗列,但是 Spring Security真正的过滤器体系才是我们了解它是如何进行"认证"、“授权”、“防止利用漏洞”的关键. Servlet Filter体系. 这里我们以 Servlet Web为讨论目标, Reactive Web暂不讨论.

Spring Boot 使用Spring security 集成CAS - CSDN博客

- -
      创建Maven工程:springboot-security-cas.       创建工程后,打开pom.xml,在pom.xml中加入以下内容:.           .           . 3.创建application.properties.

奔的家园 | CAS 与 Spring Security 3.1整合配置详解

- - Delicious/searchfull
该方式通过获取CAS系统里的角色,来支持CAS与Spring Security的关联,注意该文章authorities部分. 一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分. 用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统.

spring security 3中推荐使用BCrypt算法加密密码

- - jackyrong
spring security 3中推荐使用BCrypt算法加密密码了,以前使用的是md5,. Md5PasswordEncoder 和 ShaPasswordEncoder,现在不推荐了,推荐用bcrpt. Bcrpt中的salt可以是随机的,比如:.   其中strenth为长度. 已有 0 人发表留言,猛击->> 这里<<-参与讨论.

Spring security oauth2最简单入门环境搭建--二、干货

- - ITeye博客
关于OAuth2的一些简介,见我的上篇blog: http://wwwcomy.iteye.com/blog/2229889 PS:貌似内容太水直接被鹳狸猿干沉. 友情提示 学习曲线:spring+spring mvc+spring security+Oauth2基本姿势,如果前面都没看过请及时关闭本网页.

Spring Security判断用户是否已经登录 - 简书

- -
方法一、JSP中检查user principal. 需要:.

盘点 Spring Security 框架中的八大经典设计模式

- - SegmentFault 最新的文章
上次有小伙伴建议,源码分析太枯燥了,要是能够结合设计模式一起来,这样更有助于大家理解 Spring Security 源码,同时还能复习一波设计模式. 因此松哥今天就试着整一篇,和大家来聊一聊 Spring Security 中涉及到的设计模式,不过 Spring Security 中涉及到的设计模式还是非常多的,松哥这里讲几个,剩下的欢迎小伙伴们留言补充.