欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

史上最简单的Spring Security教程(二十二):自定义AccessDecisionManager实现简单的访问决策

程序员文章站 2022-06-02 23:23:03
...

 

​在前面讲过的资源权限动态控制业务场景中,我们使用了 Spring Security 框架默认的 AccessDecisionManager,即

AffirmativeBased。能实现的访问决策即为任一 AccessDecisionVoter 授予权限,即代表授予访问权限。但是我们只添加了一个 AccessDecisionVoter ,即 RoleVoter

既然如此,我们就可以简化一下这些逻辑,直接自定义一个新的 AccessDecisionManager,其决策逻辑为:当前请求所需的所有 ConfigAttribute 传递给 AccessDecisionVoter 进行决策,只要任一与用户拥有 GrantedAuthority 匹配,即代表授予访问权限。

public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) throws AccessDeniedException {
        Collection<? extends GrantedAuthority> authorities = extractAuthorities(authentication);
    for (ConfigAttribute attribute : attributes) {
        if (this.supports(attribute)) {
            // Attempt to find a matching granted authority
            for (GrantedAuthority authority : authorities) {
                if (attribute.getAttribute().equals(authority.getAuthority())) {
                    return;
                }
            }
            logger.warn("current user not have the '{}' attribute.", attribute);
        }
    }
    logger.warn("current request should be have at least one of the attributes {}.", attributes);
    throw new AccessDeniedException("Access is denied.");
}

这样一来,可以不用添加 RoleVoter,同时,也能满足当前的业务场景。

注意,需要保证 UserDetailsService 中授予的角色权限标识 和 SecurityMetaDataSource 中组织的请求需要的角色权限标识一致即可

接下来修改一下 Spring Security 的配置,来尝试一下吧。

private AccessDecisionManager accessDecisionManager() {
    return new AnyMatchBased();
}

启动系统,访问个人中心,此时用户拥有 User、User_2 角色,可以正常访问。

史上最简单的Spring Security教程(二十二):自定义AccessDecisionManager实现简单的访问决策

如果 User_2 角色不存在,可参考如下文章中的内容,其中有关于 User_2 角色的相关初始化sql:史上最简单的Spring Security教程(二十):自定义AccessDecisionVoter实现必须全部拥有请求所需权限才可访问的需求

然后,删除任一角色与用户的映射关系(SYS_ROLE_USER),注意提前备份要删除的数据。再退出登录、重新登录系统,访问个人中心,发现依然可以正常访问。

关于为何要先退出登录、重新登录,前面已经讲过具体原因,可自行查看如下内容史上最简单的Spring Security教程(二十):自定义AccessDecisionVoter实现必须全部拥有请求所需权限才可访问的需求

最后,删除所有的角色映射关系,再退出登录、重新登录系统,访问个人中心。此时,已不能正常访问该功能。

史上最简单的Spring Security教程(二十二):自定义AccessDecisionManager实现简单的访问决策

简单版的授权决策器实现成功。

其它详细源码,请参考文末源码链接,可自行下载后阅读。

我是银河架构师,十年饮冰,难凉热血,愿历尽千帆,归来仍是少年! 

如果文章对您有帮助,请举起您的小手,轻轻【三连】,这将是笔者持续创作的动力源泉。当然,如果文章有错误,或者您有任何的意见或建议,请留言。感谢您的阅读!

文章不定时更新,可微信搜索「银河架构师」,精彩内容,先睹为快!

相关标签: Web安全