此文章属于ruoyi项目实战系列

ruoyi系统在前端主要通过权限字符包含与否来动态显示目录和按钮。为了防止通过http请求绕过权限限制,后端接口也需要进行相关权限设计。

@PreAuthorize使用

由于对@PreAuthorize原理还不够深入了解,所以此处只粗浅讲解在ruoyi项目是如何应用的。

在请求调用接口前,被@preAuthorize注解的接口需要首先通过验证。通过注解参数value()返回值true和false来判断是否有权限。

public @interface PreAuthorize {
String value();
}

Ruoyi并没有使用原生的Spel表达式,而是使用了自定义的PermissionService类,通过其中自定义方法hasPermi(String Permission) 来进行权限判断。注解使用举例:@PreAuthorize("@ss.hasPermi('system:menu:list')")

public boolean hasPermi(String permission)
{
if (StringUtils.isEmpty(permission))//用注解就必须有permission值
{
return false;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
if (StringUtils.isNull(loginUser) ||
CollectionUtils.isEmpty(loginUser.getPermissions()))
{
return false;
}
return hasPermissions(loginUser.getPermissions(), permission); private boolean hasPermissions(Set<String> permissions, String permission)
{
return permissions.contains(ALL_PERMISSION) ||
permissions.contains(StringUtils.trim(permission)); //判断是否持有"所有权限”字符,或者持有该权限
}

接口权限校验流程

粗略用两个例子来讲解前端请求如何经过后端接口权限校验。

Login匿名请求

  1. Login请求路径是/login,在过滤器链中被AnnoymousAuthenticationFilter添加匿名authentication到Spring上下文里。由于/login请求在SecurityConfig.java里设置成匿名请求,所以可以成功到达SysLoginController。

  2. 调用SysLoginService.login方法,关键的一行命令:

    Authentication authentication = authenticationManager
    .authenticate(new UsernamePasswordAuthenticationToken(username, password));

    authenticationManager.authenticate()是钩子方法,在AbstractUserDetailsAuthenticationProvider中实现,会根据传入的token类型来自动选择,此处UsernamePasswordAuthenticationToken将由DaoAuthenticationProvider来处理(不清楚的话可以前后打两个断点看调用栈)。

  3. 在DaoAuthenticationProvider中可以看到关键的一行:

    UserDetails loadedUser = this.getUserDetailsService()
    .loadUserByUsername(username);

    这会调用我们自定义实现的UserDetailsServiceImpl#loadUserByUsername方法(如流程图所示),获得user信息。至于为什么会使用自定义方法,因为在SecurityConfig.java中进行了配置

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
    auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
    }
  4. 生成token,然后返回。

已登录请求

已登录请求流程较简单,在流程图里的some filters里会通过自定义的JwtAuthenticationFilter,其中会通过token获得user信息,然后装入Spring的上下文,方便提取使用。

曾纠结踩坑的点

由于对SpringSecurity较陌生,虽然功能强大,但其复杂性也是大大提高,所以调试项目的同时翻看了很多入门博客文章,其中都不约而同的提到了UsernamePasswordAuthenticationFilter,可是我在实战项目中反复调试都没有看到这个过滤器的调用。

原因:Security配置文件需要添加httpSecurity.formLogin()启用表单登录才会使用该filter。查看项目使用的所有filter可以使用以下测试代码:


class RuoYiApplicationTest {
@Autowired
private FilterChainProxy filterChainProxy;
@Test
public void test() {
List<SecurityFilterChain> filterChains = filterChainProxy.getFilterChains();
for(SecurityFilterChain sfc:filterChains){
for(Filter filter:sfc.getFilters()){
System.out.println(filter.getClass().getName());
}
}
}
}

ruoyi接口权限校验的更多相关文章

  1. 使用AOP+自定义注解完成spring boot的接口权限校验

    记使用AOP+自定义注解完成接口的权限校验,代码如下: pom文件添加所需依赖: 1 <dependency> 2 <groupId>org.aspectj</group ...

  2. SpringCloud(8)---zuul权限校验、接口限流

    zuul权限校验.接口限流 一.权限校验搭建 正常项目开发时,权限校验可以考虑JWT和springSecurity结合进行权限校验,这个后期会总结,这里做个基于ZuulFilter过滤器进行一个简单的 ...

  3. Apache shiro之权限校验流程

    从张开涛blog学习后整理:http://jinnianshilongnian.iteye.com/blog/2018398 图片原图比较大,建议将图片在新的选项卡打开后100%大小浏览 在权限校验中 ...

  4. 基于Spring Aop实现类似shiro的简单权限校验功能

    在我们的web开发过程中,经常需要用到功能权限校验,验证用户是否有某个角色或者权限,目前有很多框架,如Shiro Shiro有基于自定义登录界面的版本,也有基于CAS登录的版本,目前我们的系统是基于C ...

  5. SpringBoot系列 - 集成JWT实现接口权限认证

    会飞的污熊 2018-01-22 16173 阅读 spring jwt springboot RESTful API认证方式 一般来讲,对于RESTful API都会有认证(Authenticati ...

  6. 类Shiro权限校验框架的设计和实现(2)--对复杂权限表达式的支持

    前言: 我看了下shiro好像默认不支持复杂表达式的权限校验, 它需要开发者自己去做些功能扩展的工作. 针对这个问题, 同时也会为了弥补上一篇文章提到的支持复杂表示需求, 特地尝试写一下解决方法. 本 ...

  7. 类Shiro权限校验框架的设计和实现

    前言: 之前简单集成了springmvc和shiro用于后台管理平台的权限控制, 设计思路非常的优美, 而且编程确实非常的方便和简洁. 唯一的不足, 我觉得配置稍有些繁琐. 当时我有个小想法, 觉得可 ...

  8. 【JEECG技术文档】JEECG 接口权限开发及配置使用说明

    1.功能介绍   通过接口配置实现,对接口的访问权限控制和数据权限控制,接口时REST接口,接口权限认证机制使用Json web token (JWT) 接口权限调用流程: (1)通过接口用户的用户名 ...

  9. fastDFS shiro权限校验 redis FreeMark页面静态化

    FastDFS是一个轻量级分布式文件系统,   使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传.下载等服务   FastDFS服务端有两个角色:跟踪器(tracker)和存储节点( ...

随机推荐

  1. intel 82599网卡(ixgbe系列)术语表

    Intel® 82599 10 GbE Controller Datasheet 15.0 Glossary and Acronyms 术语表 缩写 英文解释 中文解释 1 KB A value of ...

  2. 我们如何上传docker到habor上呢

    Docker 打包上传habor认证 首先在 Maven 的配置文件 setting.xml 中增加相关 server 配置,主要配置 Docker registry(远程仓库)用户认证信息. < ...

  3. MySQL 表数据多久刷一次盘?

    前言 事情是这样的,在某乎的邀请回答中看到了这个问题: - 然后当时我没多想就啪一下写下来这样的答案: 这个其实要通过 MySQL 后台线程来刷的,在 Buffer Pool 中被修改的过的 Page ...

  4. Linux shell中2>&1的含义解释

    https://blog.csdn.net/zhaominpro/article/details/82630528

  5. Python学习进度汇报

    学习进度还是比较慢的,上周五(18号晚上安装了Pycharm)就开始学,五天只到这个位置,当前一直是2倍速看黑马的Python视频,外加查看菜鸟的文档,需要加快一些进度了,后续还有后续的目标要实现,争 ...

  6. Hyperledger Fabric无排序组织以Raft共识算法启动多个Orderer服务、多组织共同运行维护Orderer服务

    前言 在Hyperledger Fabric无系统通道启动及通道的创建和删除中,我们已经完成了以无系统通道的方式启动 Hyperledger Fabric 网络,并将链码安装到指定通道.但目前为止,实 ...

  7. 基于Kubernetes构建企业Jenkins master/slave CI/CD平台

    搭建平台目的: k8s中搭建jenkins master/slave架构,解决单jenkins执行效率低,资源不足等问题(jenkins master 调度任务到 slave上,并发执行任务,提升任务 ...

  8. 1. 初识 JavaScript

    1.1 JavaScript 是什么 布兰登·艾奇(Brendan Eich,1961年-). 神奇的大哥用10天完成 JavaScript 设计. 最初命名为 LiveScript,后来在与 Sun ...

  9. python学习-Day37

    目录 今日内容详细 GIL全局解释器锁 GIL与普通互斥锁区别 GIL对程序的影响 验证多线程作用 两个大前提 关于CPU的个数 关于任务的类型 死锁现象 避免死锁的解决: 添加超时释放锁 信号量 自 ...

  10. 攻防世界-MISC:hit-the-core

    这是攻防世界MISC高手进阶区的题目,题目如下: 点击下载附件一,解压后得到一个后缀为.core的文件,用string分离一下,得到如下结果: 通过观察发现,每隔四个小写字母就可以看到一个大写字母,刚 ...