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

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

@PreAuthorize使用

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

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

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. python数据类型内置的方法

    数据类型的内置方法 在日常生活中不同类型的数据具有不同的功能 eg:表格数据文件具有处理表格的各项功能(透视表 图形化 公式计算) 视频数据文件具有快进 加速等各项功能 ... 1.整型int # 方 ...

  2. 纯css 实现充电动画

    <template>   <div class="container">     <div class="header">& ...

  3. 设置网站标题时找不到index.html问题解决

    都知道,修改网站标题在根目录index.html里修改.但是在vue3更新后,index.html就没有放这里了,放到了public中.去public中一眼就能看到.我也是去那里就找到了.

  4. Transactional事务,事务嵌套的时候,如果主事务出现问题,子事务执行不需要回滚怎么做?

    如果调用的方法在不在同一个service当中,则只需要在子事务当中的方法上方添加注解即可 下方即是:这就话代表:重新开启一个新的事务 @Transactional(propagation = Prop ...

  5. box-shadow-阴影,你真的懂吗

    大家好,我是半夏,一个刚刚开始写文的沙雕程序员.如果喜欢我的文章,可以关注 点赞 加我微信:frontendpicker,一起学习交流前端,成为更优秀的工程师-关注公众号:搞前端的半夏,了解更多前端知 ...

  6. vscode golang 不能自动补全问题

    问题描述: 使用vscode编辑go语言时,有时候会莫名其妙的代码不能自动补全,struct的属性值不能自动提示,这时候如果重新启动vscode也没有效果,就可能是gocode插件出了问题或者有了更新 ...

  7. kali 更换国内源

    打开source源 vim /etc/apt/sources.list 没有权限进行更改 获取root 权限 按 i 提示内容: E325: 注意 发现交换文件 "/var/tmp/sour ...

  8. MyCat 使用中问题记录

    MyCat问题记录: Unknown charsetIndex:255 异常消息: jvm 1 | 2022-04-27 14:09:13,337 [WARN ][$_NIOREACTOR-13-RW ...

  9. 升级gradle后。需要修改jenkin 编译java版本从1.8 到11

    错误提示 * What went wrong: A problem occurred evaluating project ':App'. > Failed to apply plugin 'c ...

  10. 蓝桥杯Web:【功能实现】菜单树检索

    [功能实现]菜单树检索 背景介绍 实际工作中很多前端攻城狮都会遇到这样一个需求:在多级菜单树中模糊搜索匹配的菜单项,并显示出来. 本题需要在已提供的基础项目中使用 Vue.js 知识,实现对已提供的二 ...