簡體   English   中英

Spring Security:安全性過濾器中引發的異常映射

[英]Spring Security: mapping of exceptions thrown inside security filter

我有自定義的安全篩選器,可以用作其他授權步驟。

篩選器檢查是否可以授權用戶,如果不應該訪問該用戶,則引發異常。

問題是, 如果我從過濾器中拋出異常則該異常不會被映射到正確的狀態代碼 (在我的情況下,我需要HTTP 403)。

我不能使用@ControllerAdvice@ExceptionHandler因為安全過濾器在處理控制器之前起作用

我以為是我做錯了,我不應該拋出異常,或者我應該拋出一個非常具體的異常。

問:有什么方法可以自動將異常從過濾器映射到正確的狀態代碼? 還是有沒有辦法實現過濾器而沒有例外?

注意:我也閱讀了這篇文章 ,但是從調試中我看到我的過濾器鏈不包含ExceptionTranslationFilter

還是有沒有辦法實現過濾器而沒有例外?

顯然,您可以直接寫入響應並從遇到身份驗證或授權失敗的那一刻起返回。 拋出異常然后進行全局處理對我來說似乎是不必要的過度工作,因為我只有一個JWT身份驗證過濾器實現-AbstractAuthenticationProcessingFilter

每當認證條件不能滿足,像JWT令牌解析問題,缺少令牌,令牌畸形等,我只需登錄錯誤,設定HttpStatus並返回nullattemptAuthentication方法。

這樣,我的整個邏輯就封裝在單個類中。 我還必須在所有情況下都發送401 ,但錯誤消息有所不同,這是通過簡單的實用程序方法處理的。

如果您必須從應用程序的許多地方進行異常處理,那么在拋出異常然后處理異常方面我沒有發現任何錯誤,在這種情況下,可以像Nicholas Smith的答案中那樣指定處理程序。

Spring推薦的方法是擁有一個實現AccessDeniedHandler@Component ,然后在擴展WebSecurityConfigurerAdapter的類WebSecurityConfigurerAdapter注冊到configure(HttpSecurity ...)方法中的.accessDeniedHandler()中。 那是針對403 ,如果您還希望包裝401錯誤,則需要擴展Http401AuthenticationEntryPoint 我將在下面重點討論403案例。

您的WebSecurityConfigurerAdapter

@Override
  protected void configure(final HttpSecurity http) throws Exception {
    ...
    http
        .csrf().disable()
        .exceptionHandling().authenticationEntryPoint(<YOUR Http401AuthenticationEntryPoint>)
        .and()
        .exceptionHandling().accessDeniedHandler(<YOUR ACCESS DENIED HANDLER>);
    ...
  }

您的AccessDeniedHandler

@Override
  public void handle(HttpServletRequest request,
                     HttpServletResponse response,
                     AccessDeniedException accessDeniedException) throws IOException, ServletException {

    response.setHeader("Content-Type", "application/hal+json;charset=UTF-8");
    response.getOutputStream()
        .print(objectMapper
            .writeValueAsString("Access Denied");
    response.setStatus(403);
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM