0


7.5 SpringBoot 拦截器Interceptor实战 统一角色权限校验

CSDN成就一亿技术人

文章目录


前言

在【7.1】管理员图书录入和修改API,当时预告过:并没有写【校验是否是管理员】的逻辑,因为是通用逻辑,会单写一篇来细讲,那么今天就来安排!

角色权限校验

,是保证接口安全必备的能力:有权限才可以操作!所以,一般对于这种通用逻辑,推荐不与主业务逻辑耦合,那么

怎么来解耦?

在SpringBoot中过滤器拦截器切面,都可以实现统一角色校验的功能解耦,为了和【3-3 】用户身份认证的拦截器方案保持一致,我们采用SpringBoot拦截器Interceptor实战统一角色权限校验!

使用AOP的话,你会实现吗?文末投票不实名,让我们有更多的互动吧~~

一、定义注解annotation

通用功能定义在tg-book-common中

我们最终实现的效果是:加了@Role注解以后,这个接口只有管理员才能访问,学生访问接口就会报错:无权限!

下面定义一个

角色注解

,通过@Target 指定作用于

方法

上。

@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public@interfaceRole{/**
     * 角色id数组,默认1-管理员
     **/int[]roleIds()default{1};}

定义roleIds,是保留扩展性。若后面扩展出【校长】等其它角色,我们可以通过int数组来任意组合角色,只要拥有int数组中的任意角色id即可访问该接口。


二、拦截角色注解

1. 在拦截器哪里拦截?

显然,首先需要【用户身份认证】通过,然后再校验角色!即在AuthInterceptorpreHandle的保存至授权上下文之前:AuthContextInfo.setAuthInfo(authInfo);

@OverridepublicbooleanpreHandle(HttpServletRequest request,HttpServletResponse response,Object handler)throwsException{
    。。。省略一大堆用户身份认证代码。。。

    // TODO 校验角色:写在这!// 校验成功, 保存至认证上下文AuthContextInfo.setAuthInfo(authInfo);returntrue;}

2. 如何拦截角色注解?

可以通过将handler转成HandlerMethod以后,通过getAnnotation来获取!

HandlerMethod handlerMethod =(HandlerMethod) handler;Role role = handlerMethod.getMethod().getAnnotation(Role.class);if(role !=null){// 走到这,说明方法上加了@Role}

3. 角色如何读取?

前2步以后,我们就拿到了当前登录的userId,也拿到了接口要求的roleIds数组,所以至少有两种方案:

  1. 可以通过userId去查一次MySQL,然后判断一下角色,这种我就不实现了,你可以自己去查询实现!
  2. 将roleId保存在token中!,本文实现的是另一种方案,是为了扩展一下大家的思路,也就是不走MySQL查询的方案。

AuthContextInfo类中增加字段来承载角色:

privateInteger roleId;

在这里插入图片描述

loginByPassword中将role设置到authContextInfo.roleId

authContextInfo.setRoleId(user.getRole());

在这里插入图片描述
接着在JwtTokenProvider中定义payload的自定义字段r:

// payload的自定义字段rprivatestaticfinalStringCLAIM_ROLE="r";

在JwtTokenProvider.create中将它保存到token的payload中:

// 自定义 role.withClaim(CLAIM_ROLE, authContextInfo.getRoleId())

在这里插入图片描述

在JwtTokenProvider.verify中将它从token中解析出来:
在这里插入图片描述

4. 最后做角色校验

拿到了authInfo.getRoleId(),还知道了接口方法要求的roleIds,判断逻辑太简单了吧~ 我简单写了一下,如下:

// 校验角色HandlerMethod handlerMethod =(HandlerMethod) handler;Role role = handlerMethod.getMethod().getAnnotation(Role.class);if(role !=null){// 走到这,说明方法上加了@Roleboolean isAdmin =false;for(int roleId : role.roleIds()){if(authInfo.getRoleId().equals(roleId)){
            isAdmin =true;break;}}if(!isAdmin){
        log.info("[403]无权限, token={}", token);
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);// 别忘了返回falsereturnfalse;}}

三、应用:给管理员操作接口加注解

在实现了通用校验逻辑以后,接下来就是如何应用了!
其实就是:

加@Role注解

下面对管理员录入和修改图书接口加了注解,其它接口同理~~

在这里插入图片描述


四、PostMan测试

使用role=0的账号调用管理员API,返回403!
在这里插入图片描述

使用管理员账号则会正常执行!就不做截图了!另外,别忘了提交Git!


最后

想要看更多实战好文章,还是给大家推荐我的实战专栏–>《基于SpringBoot+SpringCloud+Vue前后端分离项目实战》,由我和 前端狗哥 合力打造的一款专栏,可以让你从0到1快速拥有企业级规范的项目实战经验!

具体的优势、规划、技术选型都可以在《开篇》试读!

订阅专栏后可以添加我的微信,我会为每一位用户进行针对性指导!

另外,别忘了关注我:天罡gg ,发布新文不容易错过: https://blog.csdn.net/scm_2008

标签: spring boot 后端 java

本文转载自: https://blog.csdn.net/scm_2008/article/details/131711216
版权归原作者 天罡gg 所有, 如有侵权,请联系我们删除。

“7.5 SpringBoot 拦截器Interceptor实战 统一角色权限校验”的评论:

还没有评论