AuthenticationException異常無法被全局異常捕獲的解決辦法


我們可以先看一下為什么不能被捕獲?

很明顯JwtFilter的祖宗是Fliter,而我們自己定義的全局異常處理器@RestControllerAdvice

這個注解是 @ControllerAdvice 和 @ResponseBody的結合體。

主要是針對的我們controller控制器的。而過濾器是在這個之前進行處理的。我們在Filter里面進行拋出異常,那么該怎么做呢?

@RestControllerAdvice
public class GlobalExceptionHandler {
    xxxxx
}

MyRealm域對象

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    //對傳入的token進行類型轉換
    MyJsonWebToken myJsonWebToken = (MyJsonWebToken) authenticationToken;
    String token = myJsonWebToken.getCredentials() + "";
    //直接通過redis進行判斷
    RbacManagerDTO rbacManagerDTO = (RbacManagerDTO) redisTemplate.opsForValue().get(token);
    if (null != rbacManagerDTO) {
        return new SimpleAuthenticationInfo(token, token, "myRealm");
    } else {
        throw new AuthenticationException("token已過期,請重新登錄");
    }
}

Jwt驗證步驟

@SneakyThrows
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
    //檢查認證請求,判斷請求頭中是否有token,有就執行登錄驗證
    if (isLoginAttempt(request, response)) {
        try {
            //執行登錄
            executeLogin(request, response);
            //全局異常無法捕獲filter里的異常,這里就使用請求轉發給controller,返回給前端
        } catch (AuthenticationException e) {
            response401(request, response, e.getMessage());
        } catch (Exception e) {
            //如果沒有token,那么就請求轉發到到401請求,讓410controller返回前端一個請求
            response401(request, response, "其他異常");
        }
    } else {
        //沒有token
        response401(request, response, "沒有token");
    }
    return true;
}

 具體實現response401()方法

private void response401(ServletRequest request, ServletResponse response
        , String msg) throws ServletException, IOException {
    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    HttpServletResponse httpServletResponse = (HttpServletResponse) response;
    try {
        // //請求轉發401controller
        httpServletRequest.getRequestDispatcher("/rbacManager/401/" + msg).forward(request, response);
    } catch (ServletException | IOException e) {
        e.printStackTrace();
    }
}

401專屬controller

@GetMapping("/401/{msg}")
public ResponseResult error (@PathVariable("msg") String msg){
    return new ResponseResult(400,msg,null);
}

這樣前台就可以收到我們的狀態了。而我們的域對象的異常也算是成功返回給前端了。ヾ(✿゚▽゚)ノ

結果展示:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM