When Shrio has no permission, he is forced to log out. Shiro's AuthorizationException and UnauthorizedException control

A recent project uses Shiro for permission control, and uses the @RequiresPermissions annotation on the Controller to control the interface, as shown in the figure:

/**
     * 删除
     * @param id
     * @return
     */
    @RequiresPermissions("article-experience:remove")
    @PostMapping("/remove/{id}")
    public ResultVO removeArticle(@PathVariable Integer id) {
    
    
        return articleService.removeArticle(id, ArticleConstant.TYPE_EXPERIENCE);
    }

It stands to reason that users without this [article-experience:remove] permission cannot perform this operation, and the operation will be intercepted by Shrio.
When I used an unauthorized user to perform this operation, it was indeed blocked, but not only did not return a custom no-authority prompt, but I was forced to log out directly.

After checking, it was found that it was caught by the following ExceptionHandle:

/**
     * 登录控制
     */
    @ExceptionHandler({
    
    AuthorizationException.class, UnauthorizedException.class})
    public ResultVO authorizationException(Exception e) {
    
    
        if (e instanceof CustomException) {
    
    
            CustomException customException = (CustomException) e;
            return ResultUtil.error(customException.getCode(), customException.getMessage());
        } else {
    
    
            LOGGER.error("【系统异常---authorizationException】{}",e);
            if("prod".equals(env)){
    
    
                return ResultUtil.error(JavaCodeEnum.LOGIN_EXPIRED);
            }
            return ResultUtil.error(JavaCodeEnum.LOGIN_EXPIRED.getCode(), e.getMessage());
        }
    }

The exception prompt returned in the above code is JavaCodeEnum.LOGIN_EXPIRED, which is defined in the project enumeration: insert image description here
Although the purpose of the current operation is to verify whether there is permission to operate, the code returned after being captured by ExceptionHandle here is the same as the logout agreed with the front end before The code is the same, the front end will clear the user token according to the code we capture and return, and the login page will return to the login page if the login fails, which is why it will be "forced to log out".

Why was it captured?

The problem lies in the capture of ExceptionHandle, so we have to analyze how it is written:
insert image description here
First, the @ExceptionHandler({}) annotation is generally used to customize exceptions. It can be thought of as an exception interceptor (processor).
Here it declares to capture AuthorizationException and UnauthorizedException exception classes,
then whether it is authorization exception or unauthorized exception, it will come in and catch, and the returned code is the same. Naturally, the above problem will occur, even if it is only without permission, it will be caught Force logout.

Solution

The simplest and crudest way is to write AuthorizationException (authorization exception) and UnauthorizedException (unauthorized exception) separately:
insert image description here
After writing this separately, AuthorizationException authorization exception (whether the login is successful) and UnauthorizedException unauthorized exception (whether the login is authorized or not) will be captured separately.
Note that the code returned after capture should also return the corresponding code according to the corresponding exception.

Guess you like

Origin blog.csdn.net/Ivy_Xinxxx/article/details/124836302