7.5 SpringBoot Interceptor Interceptor Actual Combat Unified Role Permission Verification

CSDN achieves 100 million technicians


foreword

In [ 7.1 ] the administrator’s book entry and modification API, it was announced at the time: the logic of [checking whether you are an administrator] is not written, because it is a general logic, I will write a separate article to explain it in detail, so I will arrange it today!

角色权限校验, is a necessary ability to ensure the security of the interface: you can only operate with permission! Therefore, generally for this general logic, it is recommended not to be coupled with the main business logic, then怎么来解耦?

Filters , interceptors , and aspects in SpringBoot can all realize the functional decoupling of unified role verification. In order to be consistent with the interceptor scheme of [ 3-3 ] user identity authentication, we use the SpringBoot interceptor Interceptor to actually perform unified role permission verification!使用AOP的话,你会实现吗?文末投票不实名,让我们有更多的互动吧~~


1. Definition annotation annotation

Common functions are defined in tg-book-common

The final effect we achieved is: after adding the @Role annotation, only administrators can access this interface, and students will report an error when accessing the interface: No permission!

The following defines one 角色注解, which is specified by @Target to act 方法on.

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

Define roleIds to preserve scalability. If other roles such as [principal] are expanded later, we can combine roles arbitrarily through the int array, as long as we have any role id in the int array, we can access this interface.


2. Intercept role annotation

1. Where is the interceptor intercepted?

Obviously, the [User Identity Authentication] needs to be passed first, and then the role is verified! That is, before the preHandle of AuthInterceptor is saved to the authorization context: AuthContextInfo.setAuthInfo(authInfo);

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
    。。。省略一大堆用户身份认证代码。。。

    // TODO 校验角色:写在这!
    

    // 校验成功, 保存至认证上下文
    AuthContextInfo.setAuthInfo(authInfo);
    return true;
}

2. How to intercept role annotations?

It can be obtained through getAnnotation after converting handler to HandlerMethod!

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

3. How to read the role?

After the first two steps, we get the currently logged in userId and the roleIds array required by the interface, so there are at least two options:

  1. You can check MySQL once by userId, and then judge the role. I won’t realize this, you can query it yourself!
  2. 将roleId保存在token中!, what this article implements is another solution, which is to expand everyone's thinking, that is, the solution that does not use MySQL query.

Add fields to the AuthContextInfo class to carry roles:

private Integer roleId;

insert image description here

Set role to authContextInfo.roleId in loginByPassword

authContextInfo.setRoleId(user.getRole());

insert image description here
Then define the custom field r of payload in JwtTokenProvider :

// payload的自定义字段r
private static final String CLAIM_ROLE = "r";

Save it to the token payload in JwtTokenProvider.create :

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

insert image description here

Parse it from token in JwtTokenProvider.verify :
insert image description here

4. Final character verification

I got authInfo.getRoleId(), and I also know the roleIds required by the interface method. The judgment logic is too simple~ I wrote it briefly, as follows:

// 校验角色
HandlerMethod handlerMethod = (HandlerMethod) handler;
Role role = handlerMethod.getMethod().getAnnotation(Role.class);
if (role != null) {
    
    
    // 走到这,说明方法上加了@Role
    boolean 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);
        // 别忘了返回false
        return false;
    }
}

3. Application: Annotate the administrator operation interface

After implementing the general verification logic, the next step is how to apply it!
Actually it is:加@Role注解

The following adds annotations to the administrator's entry and modification of the book interface, and the other interfaces are the same~~

insert image description here


Four, PostMan test

Use the account with role=0 to call the administrator API, and return 403!
insert image description here

Using the administrator account will execute normally! No more screenshots! Also, don't forget to commit to Git!


at last

If you want to read more practical articles, I still recommend my practical column –> "Based on SpringBoot+SpringCloud+Vue Separation of Front-end and Back-end Projects", a column jointly created by me and the front-end dog brother, which allows you to quickly have enterprise-level standardized project combat experience from 0 to 1 !

Specific advantages, planning, and technology selection can all be read in " The Beginning "!

After subscribing to the column, you can add my WeChat, and I will provide targeted guidance for each user!

In addition, don't forget to follow me: Tiangang gg , it is not easy to miss new articles: https://blog.csdn.net/scm_2008

Guess you like

Origin blog.csdn.net/scm_2008/article/details/131711216