2014-10-05 154 views
4

美好的一天。春季開機+春季安全:如何取消基本身份驗證表格

我在Spring引導自動配置的應用程序中使用了Spring安全性。我的目標是設置基本身份驗證,以便標準瀏覽器的基本身份驗證表單在401上不顯示。從Google發現要實現它,我需要將默認的「WWW-Authenticate」標題更改爲不同於「基本xxxxx「。

爲了做到這一點,我宣佈一個過濾器:

@Bean 
@Order(Integer.MAX_VALUE) 
public Filter customAuthFilter() { 
    return new Filter() { 

     @Override 
     public void init(FilterConfig fc) throws ServletException { 
     } 

     @Override 
     public void doFilter(ServletRequest sreq, ServletResponse sresp, FilterChain fc) throws IOException, ServletException { 
      HttpServletRequest req = (HttpServletRequest) sreq; 
      HttpServletResponse resp = (HttpServletResponse) sresp; 

      fc.doFilter(req, resp); 
      log.info("filter"); 
      log.info("status " + resp.getStatus()); 
      if(resp.getStatus() == 401) { 
       resp.setHeader("WWW-Authenticate", "Client-driven"); 
      } 
     } 

     @Override 
     public void destroy() { 
     } 
    }; 

從我看到我的過濾器成功應用的認可,並採取了處理響應(我看到的doFilter日誌消息)參與的日誌。但瀏覽器收到的實際響應仍包含標準的「WWW-Authenticate」標頭。看起來有人超越了我的標題,因爲我沒有確切的線索。

請問有人能給個建議嗎?

回答

5

通過使用自定義入口點問題解決了:在請求頭(Spring Security的4.2.2.RELEASE測試): 「XMLHttpRequest的X-要求,以」

protected void configure(HttpSecurity http) throws Exception { 
     http 
      .authorizeRequests() 
      .antMatchers("/rest/**").authenticated() 
      .and().httpBasic().authenticationEntryPoint(new AuthenticationEntryPoint() { 
       @Override 
       public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { 
        String requestedBy = request.getHeader("X-Requested-By"); 
        log.info("X-Requested-By: " + requestedBy); 
        if(requestedBy == null || requestedBy.isEmpty()) { 
         HttpServletResponse httpResponse = (HttpServletResponse) response; 
         httpResponse.addHeader("WWW-Authenticate", "Basic realm=Cascade Realm"); 
         httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); 
        } else { 
         HttpServletResponse httpResponse = (HttpServletResponse) response; 
         httpResponse.addHeader("WWW-Authenticate", "Application driven"); 
         httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); 
        } 
       } 
      }); 
} 
1

Spring Security過濾器也會被添加到最低優先級,所以它可能是你的上游。你可以嘗試一個更低的順序。處理401響應的傳統方法是使用AuthenticationFailureHandler,但我想我可以看到爲什麼你可以這樣做,因爲基本認證已經存在。

+0

謝謝你的答覆。我已經嘗試了你提到的傳統方式 - 確實很有用,但它不是我正在尋找的。看起來AuthenticationFailureHandler只是在錯誤的身份驗證嘗試(用戶在登錄表單中提交的無效憑證)時觸發的。但是我正在尋找的是在答覆HTTP客戶端之前透明地自定義某些響應頭的方法。在原始servlet環境中,我可以通過過濾器來實現,但在Spring中,這種方法似乎工作方式不同...... – skapral 2014-10-07 13:09:28

+0

過濾器是過濾器。我預見到的唯一問題是,您可能需要屏蔽響應,以防止它在您的過濾器有機會完成任務之前提交。但是你說你已經有了這個工作,所以你應該做的就是按照正確的順序進行。這很簡單(只需更改訂單)。 – 2014-10-07 14:28:21

0

只需添加。

有關詳細信息,HttpBasicConfigurer值得查找。

下面是使用curl我的測試結果:

hanxideMacBook-Pro:~ hanxi$ curl -u "13980547109:xxx" -v -d "" -H "X-Requested-With: XMLHttpRequest" http://sales.huoxingy.com/api/v1/sales/login 
* Trying 101.37.135.20... 
* TCP_NODELAY set 
* Connected to sales.huoxingy.com (101.37.135.20) port 80 (#0) 
* Server auth using Basic with user '13980547109' 
> POST /api/v1/sales/login HTTP/1.1 
> Host: sales.huoxingy.com 
> Authorization: Basic MTM5ODA1NDcxMDk6MTIzNDU2 
> User-Agent: curl/7.54.0 
> Accept: */* 
> X-Requested-With: XMLHttpRequest 
> Content-Length: 0 
> Content-Type: application/x-www-form-urlencoded 
> 
< HTTP/1.1 200 
< Server: nginx/1.12.1 
< Date: Thu, 21 Sep 2017 01:43:13 GMT 
< Content-Length: 0 
< X-Content-Type-Options: nosniff 
< X-XSS-Protection: 1 
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate 
< Pragma: no-cache 
< Expires: 0 
< X-Frame-Options: DENY 
< X-XSS-Protection: ; mode=block 
< x-auth-token: 2f595113-cdba-4394-8ca0-bcd72239bea5 
< Set-Cookie: CONTAINERID=efc390abdb189a10c55e0672b07cfe1c7d665be4db9ad40e122475e5cdff605d; path=/