六、SpringSecurity实现动态权限控制

2023-10-28

前面已经实现了登陆,即认证,下面是登陆之后的鉴权(即某些角色只能访问特定的资源)

/**
 * @auther Mr.Liao
 * @date 2019/8/20 20:24
 */
@Component
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
    @Autowired
    private MenuMapper menuMapper;
    
    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        //获取请求的url
        String requestUrl = ((FilterInvocation) object).getRequestUrl();
        //获取当前请求需要的角色信息,拿url去menu表中匹配,查看是访问的那个menu下的资源,根据menuId 获取到role信息
        List<Menu> menuList = menuMapper.findAllMenu();
        for (Menu menu : menuList) {
            //如果请求的路径包含在某个menu的url中,且能访问该资源的角色信息存在
            if (antPathMatcher.match(menu.getUrl(),requestUrl) && menu.getRoles().size() > 0) {
                List<Role> roles = menu.getRoles();
                int size = roles.size();
                //定义一个数组,来接收能访问该资源的角色
                String[] roleNameArray = new String[size];
                for (int i = 0; i < size; i++) {
                    roleNameArray[i] = roles.get(i).getRoleAuthority();
                }
                return SecurityConfig.createList(roleNameArray);
            }
        }
        //如果遍历完menu之后没有匹配上,说名访问该资源不需要权限信息,设置一个登陆就能访问的角色
        return SecurityConfig.createList("ROLE_login");
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return FilterInvocation.class.isAssignableFrom(clazz);
    }
}
/**
 * @auther Mr.Liao
 * @date 2019/8/20 21:18
 */
@Component
public class MyAccessDecisionManager implements AccessDecisionManager {
    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
        Iterator<ConfigAttribute> iterator = configAttributes.iterator();
        while (iterator.hasNext()){
            ConfigAttribute configAttribute = iterator.next();
            //访问该请求url需要的角色信息
            String needRole = configAttribute.getAttribute();
            //如果只是登陆就能访问,即没有匹配到资源信息
            if ("ROLE_login".equals(needRole)){
                //判断是否登陆,没有登陆则authentication是AnonymousAuthenticationToken接口实现类的对象
                if (authentication instanceof AnonymousAuthenticationToken){
                    throw new BadCredentialsException("未登录");
                } else return;
            }
            //如果匹配上了资源信息,就拿登陆用户的权限信息来对比是否存在于已匹配的角色集合中
            for (GrantedAuthority authority : authorities) {
                if (authority.getAuthority().equals(needRole)){
                    return;
                }
            }
        }
        //如果没有匹配上,则权限不足
        throw new AccessDeniedException("权限不足");
    }

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}
@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        RespBean respBean = new RespBean(403, "权限不足", e.getMessage());
        out.write(new ObjectMapper().writeValueAsString(respBean));
        out.flush();
        out.close();
    }
}

配置:

@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserLoginService userLoginService;
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    private SuccessHandler successHandler;
    @Autowired
    private FailureHandler failureHandler;
    @Autowired
    private ImageCodeFilter imageCodeFilter;
    @Autowired
    private DataSource dataSource;
    @Autowired
    private MySecurityMetadataSource mySecurityMetadataSource;
    @Autowired
    private MyAccessDecisionManager myAccessDecisionManager;
    @Autowired
    private MyAccessDeniedHandler myAccessDeniedHandler;

    @Bean//PersistentTokenRepository记住我功能的工具类
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        return tokenRepository;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userLoginService)
                .passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers( "/login_p.html", "/authentication/request","/favicon.ico","/code/image");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(imageCodeFilter, UsernamePasswordAuthenticationFilter.class)
                .authorizeRequests()
                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O o) {
                        o.setSecurityMetadataSource(mySecurityMetadataSource);
                        o.setAccessDecisionManager(myAccessDecisionManager);
                        return o;
                    }
                })
                .and()
                    //表单登陆配置
                    .formLogin()
                    .loginPage("/authentication/request").loginProcessingUrl("/user/login")
                    .usernameParameter("username").passwordParameter("password")
                    .successHandler(successHandler).failureHandler(failureHandler)
                    .permitAll()
                .and()
                    //记住我配置
                    .rememberMe()
                    .tokenRepository(persistentTokenRepository())
                    .tokenValiditySeconds(20)
                    .userDetailsService(userLoginService)
                .and()// 关闭跨站请求伪造防护
                    .csrf().disable()
                    .exceptionHandling().accessDeniedHandler(myAccessDeniedHandler);
    }
}

测试接口:

@RestController
public class TestController {
    @GetMapping("/emp/basic/test")
    public String test1(){
        return "员工资料接口";
    }

    @GetMapping("/emp/recruitment/test")
    public String test2(){
        return "员工招聘接口";
    }

    @GetMapping("/salary/change/test")
    public String test3(){
        return "工资调整接口";
    }

    @GetMapping("/salary/statistics/test")
    public String test4(){
        return "工资统计接口";
    }

    @GetMapping("/per/evaluation/test")
    public String test5(){
        return "业绩考核接口";
    }

    @GetMapping("/per/statistics/test")
    public String test6(){
        return "业绩统计接口";
    }

    @GetMapping("/test")
    public String test7(){
        return "登陆就能访问的接口";
    }
}

在这里插入图片描述
登陆张三
在这里插入图片描述
访问结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
修改用户的权限信息时,将用户和角色的id添加到user_role表中,调整角色能访问的资源信息时,将关联的角色和资源信息添加到role_menu表中

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

六、SpringSecurity实现动态权限控制 的相关文章

  • 一个注解搞定Spring Security 忽略拦截

    Copyright 2021 2022 the original author or authors Licensed under the Apache License Version 2 0 the License you may not
  • Spring Cloud 微服务安全

    Author Hedon Github spring security oauth2 0 前篇 Spring Cloud 微服务安全 一 API 安全 Spring Cloud 微服务安全 二 网关安全 Spring Cloud 微服务安全
  • springsecurity oauth2中refresh token模式需要注意的点

    oauth2官方只有4种授权方式 不过springsecurity oauth2把refresh token也归为authorizedGrantTypes的一种 因此 springsecurity的oauth2实现有5中模式 authori
  • SpringSecurity------WebSecurityConfiguration配置类

    SpringSecurity WebSecurityConfiguration配置类 一 WebSecurityConfiguration是怎样被加载的 二 WebSecurityConfiguration主要做了什么 三 WebSecur
  • 六、SpringSecurity实现动态权限控制

    前面已经实现了登陆 即认证 下面是登陆之后的鉴权 即某些角色只能访问特定的资源 auther Mr Liao date 2019 8 20 20 24 Component public class MySecurityMetadataSou
  • Spring Security3.1 最新配置实例 .

    这几天学习了一下Spring Security3 1 从官网下载了Spring Security3 1版本进行练习 经过多次尝试才摸清了其中的一些原理 本人不才 希望能帮助大家 还有 这次我第二次写博客啊 文体不是很行 希望能让观看者不产生
  • Spring security安全登录-当AJAX遇上Redirect

    前言 最近做平台引入spring security做为安全认证框架 在登录的时候使用的ajax的请求方式 最开始的做法是调用登录的接口 成功后再前端使用window location href index html的方式跳转到希望的页面 考
  • Spring Security怎么给方法配置权限的?

    前言 突然反应过来 前面一篇好像突然讲的太深了 应该先从入门开始 结果直接整源码分析 导致一些不了解Spring Security的朋友不太懂用 本篇非常重要 主要讲怎么给你的函数添加权限管理 本章内容 动态管理权限规则 怎么根据目标资源从
  • 学习SpringSecurity这一篇就够了

    目录 一 SpringSecurity 框架简介 1 1 概要 1 2 Spring Security到底能干什么 1 3 常用术语 1 4 历史 1 5 同款产品对比 1 6 模块划分 二 SpringSecurity 入门案例 2 1
  • SpringMVC+Apache Shiro+JPA(hibernate)案例教学(一)整合配置

    序 关于标题 说是教学 实在愧不敢当 但苦与本人文笔有限 实在找不到更合理 谦逊的词语表达 只能先这样定义了 其实最真实的想法 只是希望这个关键词能让更多的人浏览到这篇文章 也算是对于自己写文章的一个肯定吧 关于内容 再写这系列文章之前 本
  • Java应用程序安全框架

    从零打造项目 系列文章 工具 比MyBatis Generator更强大的代码生成器 ORM框架选型 SpringBoot项目基础设施搭建 SpringBoot集成Mybatis项目实操 SpringBoot集成MybatisPlus项目实
  • 5. Spring Boot Security资源管理持久化的实现

    1 概述 本次给大家讲一下如何实现资源的持久化 2 表机构以及数据 insert into sys user demo user id user name user passwd values 1 admin admin insert in
  • Spring Security - 06 修改默认的用户名和密码

    文章目录 环境 项目结构 修改默认的用户名和密码 测试 参考 环境 操作系统 Windows 10 x64 集成开发环境 Spring Tool Suite 4 Version 4 12 1 RELEASE Build Id 2021102
  • SpringBoot+Spring Security+JWT

    SpringBoot Spring Security JWT
  • 升级到spring security5遇到的坑-密码存储格式

    遇到的问题 将spring security oauth2 包括spring security 升级到最新 代码没有改动 运行项目没有报错 但是页面登陆时报错 There is no PasswordEncoder mapped for t
  • Spring Security跨域问题解决

    前文介绍了 Spring 处理跨域问题的三种方案 现在来看看 Spring Security 的跨域问题解决方案 共有三种方案 摘自 深入浅出Spring Security 在实际项目使用中 推荐使用第三种方案 11 3 3 专业解决方案
  • 简单几步升级Spring security4.x升级到5.x

    本次升级源自一次安全漏洞提醒 Spring Security 身份认证绕过漏洞 CVE 2022 22978 现将漏洞相关详情下发 如系统使用了受影响版本软件 请参照处置建议及时完成处理 风险名称 Spring Security 身份认证绕
  • SpringSecurity最全实战讲解

    文章目录 Spring Security 专题 一 基本概念 认证 授权 会话 RBAC模型 二 一个自己实现的权限模型 BasicAuth 三 SpringBoot Security 快速上手 1 项目搭建步骤 2 用SpringBoot
  • Spring Security 自定义用户认证

    一 PasswordEncoder 在 Configuration注解的类下注入bean import org springframework security crypto bcrypt BCryptPasswordEncoder imp
  • 若依开源框架登录扩展Springboot+security,密码、验证码多种登录

    自定义登录扩展类 继承DaoAuthenticationProvider类型 重写additionalAuthenticationChecks方法 CustomLoginAuthenticationProvider java package

随机推荐

  • LinuxMint上硬盘重装LinuxMint(理论上ubuntu也行)

    主要思路是通过修改引导程序 grub2 的配置文件 boot grub grub cfg 使计算机开机后引导硬盘中存放的系统镜像文件 iso 步骤 1 将下载好的系统镜像文件放入硬盘中一个不会被格式化的分区中 为了方便我直接放在了sda1的
  • C语言可以开发哪些项目?

    C语言是我们大多数人的编程入门语言 对其也再熟悉不过了 不过很多初学者在学习的过程中难免会出现迷茫 比如 不知道C语言可以开发哪些项目 可以应用在哪些实际的开发中 这些迷茫也导致了我们在学习的过程中不知道如何学 学什么 所以 总结这个列表
  • treeSelect节点搜索

    antd中treeSelect的filterTreeNode用法 节点搜索 以下图为例 树形搜索展开后 有以下几个选项 如果我想要搜索其中 产品中心 那直接搜索关键词 产品 即可 我搜索后并未显示我想要的结果 而是为空 这就需要用到 fil
  • 总结JS 常用函数

    希望本文总结的内容能给各位看官带来焕然一新的感觉 另外 如果你们有什么值得推荐的js技巧 欢迎在评论中补充 我可以收纳在本文中 PS 此文档会持续新增内容 Ajax请求 jquery ajax函数 我自己封装了一个ajax的函数 代码如下
  • sudo 之后 unable to resolve host的问题解决办法

    gedit etc hosts 127 0 0 1 localhost 127 0 0 1 Masterback或者其他 把后面的Masterback 或者其他改成新的主机名 应该是最近修改过主机名 也就是用户名 后面的部分
  • _WIN32和_WIN64区别

    WIN32 是一个预定义的宏 用于判断当前编译环境是否为 Windows 操作系统 当使用 MSVC 编译器编译 Windows 应用程序时 无论是 32 位还是 64 位的 Windows 环境 WIN32 宏都会被定义 你可以使用条件编
  • 蓝桥杯2021年第十二届国赛真题-和与乘积

    题目描述 给定一个数列 A a1 a2 an 问有多少个区间 L R 满足区间内元素的乘积等于他们的和 即 aL aL 1 aR aL aL 1 aR 输入格式 输入第一行包含一个整数 n 表示数列的长度 第二行包含 n 个整数 依次表示数
  • SetTimer在无窗口和有窗口线程的使用 .

    今天犯了一个粗心的错误 在无窗口线程中 SetTimer中设置计时器ID 而WM TIMER消息响应函数中得到的计时器ID却不是之前设置的计时器ID 111902 cpp Defines the entry point for the co
  • Prepo —— 图标转化器

    Prepo for mac是Mac os平台上的一款非常不错的Mac图像处理软件 Prepo for mac基于Mac和iOS的一款免费且方便的图标转化器 它可以帮助设计师快速的导出各种尺寸的图标 设计师通过Prepo把任何格式的图片文件转
  • img引入的svg图片,悬浮时怎么修改颜色?

    实现效果 鼠标悬浮在这一行 让这行的文字和svg图片颜色发生变化 因为是用 img标签引入页面 使用fill属性是无效的 css核心代码 active hover transform scale 0 98 img filter drop s
  • Transaction silently rolled back because it has been marked as rollback-only Spring事务嵌套问题

    Transaction silently rolled back because it has been marked as rollback only Spring 事务嵌套问题 添加命令 catch中添加 TransactionAspe
  • Springboot升级到2.x后gridFsTemplate.findOne(query)返回类型由GridFSDBFile改为GridFSFile导致的问题

    问题描述 gridFsTemplate findOne query 返回类型由GridFSDBFile改为GridFSFile导致的问题 文件下载时下面的代码不可用 GridFSDBFile gridFSDBFile new GridFSD
  • java.lang.NoClassDefFoundError: javax/servlet/ServletContext(可能报错原因,不可盖全)

    例如一下jar包版本低 提高版本即可 version 5 0 5RELEASE
  • ArcGIS中统计渔网中栅格人口密度

    文章目录 前言 一 人口数据获取 来源一 中科院地理所公开数据集 来源二 WorldPop数据集 二 人口格网统计步骤 1 创建渔网 2 人口数据处理 2 1 栅格转点 2 2 空间插值 处理人口缺失数据 2 3 空间连接 渔网人口统计 总
  • IGBT简介、结构及原理

    所谓IGBT 绝缘栅双极型晶体管 是由 BJT 双极结型晶体三极管 和 MOS 绝缘栅型场效应管 组成的复合全控型 电压驱动式 功率半导体器件 其具有自关断的特征 简单讲 是一个非通即断的开关 IGBT没有放大电压的功能 导通时可以看做导线
  • ubuntu 安装微信(wechat)

    软件介绍 Wine Wine Is Not an Emulator Wine不是一个模拟器 的缩写 是一个能够在多种 POSIX compliant 操作系统 诸如 Linux Mac OSX 及 BSD 等 上运行 Windows 应用的
  • java动态上传图片_Java实现图片文件上传

    Java实现后台图片上传 将上传图片的接口进行分层 便于维护接口 接口部分 interface 将接口分为单图片上传以及多图片上传 public interface FileUploadService 单图片上传 PicUploadResu
  • 服务器装win10性能怎样,Win10 藏着不给人看的卓越性能模式到底对电脑有什么影响?...

    未来Win10的功能与稳定性趋于完善 其流行趋势会越来越大 许多游戏玩家选择也会选择 Win10 其独有的游戏模式与Xbox游戏录制功能也是对游戏的一大支持所在 今天小编就带大家来简单测试一下Win10 的卓越性能模式对游戏以及电脑性能的影
  • DispatcherServlet最全详解

    文章目录 DispatcherServlet最全详解 DispatcherServlet族谱 一 语言总结 1 DispatcherServlet初始化 2 DispatcherServlet调用组建处理请求 二 DispatcherSer
  • 六、SpringSecurity实现动态权限控制

    前面已经实现了登陆 即认证 下面是登陆之后的鉴权 即某些角色只能访问特定的资源 auther Mr Liao date 2019 8 20 20 24 Component public class MySecurityMetadataSou