2016-11-24 84 views
1

我有一個使用Jersey作爲JAX-RS實現的Spring Boot應用程序。這是我的安全配置:Spring Boot REST API/Spring Security:身份驗證失敗時返回自定義消息

@Configuration 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
@EnableWebSecurity 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired TokenAuthenticationProvider tokenAuthenticationProvider; 

    @Override 
    public void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.authenticationProvider(tokenAuthenticationProvider); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.addFilterBefore(new AuthenticationTokenFilter(), BasicAuthenticationFilter.class) 
       .csrf().disable() 
       .authorizeRequests() 
       .antMatchers("/dataHub/**") 
       .authenticated(); 
    } 
} 

我希望能夠做的就是有一個辦法趕上我的TokenAuthenticationProvider拋出的異常,並將它們轉換成我們已經商定的標準化JSON格式。有沒有辦法做到這一點?我試着添加一個自定義的AuthenticationFailureHandler,但無法讓它工作。

回答

7

WebSecurityConfigurerAdapter appraoch

HttpSecurity類有一個叫做exceptionHandling方法,其可以被用於覆蓋默認行爲。以下示例展示瞭如何定製響應消息。

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
     // your custom configuration goes here 
     .exceptionHandling() 
     .authenticationEntryPoint((request, response, e) -> { 
      String json = String.format("{\"message\": \"%s\"}", e.getMessage()); 
      response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 
      response.setContentType("application/json"); 
      response.setCharacterEncoding("UTF-8"); 
      response.getWriter().write(json);     
     }); 
} 

@ControllerAdvice appraoch - 爲什麼不能在這種情況下

工作,起初我還以爲約@ControllerAdvice映入認證例外整個應用程序。

import org.springframework.http.HttpStatus; 
import org.springframework.security.core.AuthenticationException; 

@ControllerAdvice 
public class AuthExceptionHandler { 

    @ResponseStatus(HttpStatus.UNAUTHORIZED) 
    @ExceptionHandler(AuthenticationException.class) 
    @ResponseBody 
    public String handleAuthenticationException(AuthenticationException e) { 
     return String.format("{\"message\": \"%s\"}", e.getMessage()); 
    } 

} 

在上面的例子中,JSON是人工建造的,但你可以簡單地返回將被映射到JSON從一個普通的REST控制器就像一個POJO。自Spring 4.3以來,您還可以使用@RestControllerAdvice,這是@ControllerAdvice@ResponseBody的組合。

但是,因爲達成任何控制器之前的異常由AbstractSecurityInterceptor引發和處理由ExceptionTranslationFilter這種方法是行不通的

相關問題