2017-06-05 5 views
1

私は、JSON Webトークンを使用するSpring Security & Spring SecurityアプリケーションのSpring起動に取り組んでいます。春のセキュリティフィルタでカスタムエラーを返す

私は既存のJWTの存在をチェックし、もしそうであれば、UsernamePasswordAuthenticationTokenを注入スプリング・セキュリティ・フィルタを有する:

public class AuthenticationTokenFilter extends UsernamePasswordAuthenticationFilter { 

    @Value("${api.token.header}") 
    String tokenHeader; 

    @Autowired 
    TokenUtility tokenUtility; 

    @Override 
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 

     HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; 

     String incomingToken = httpRequest.getHeader(tokenHeader); 

     if (SecurityContextHolder.getContext().getAuthentication() == null && incomingToken != null) { 

      UserDetails userDetails = null; 

      try { 

       userDetails = tokenUtility.validateToken(incomingToken); 

      } catch (TokenExpiredException e) { 

       throw new ServletException("Token has expired", e); 
      } 

      if (userDetails != null) { 

       UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); 

       authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest)); 

       SecurityContextHolder.getContext().setAuthentication(authentication); 
      } 
     } 

     filterChain.doFilter(servletRequest, servletResponse); 
    } 
} 

次のように、このフィルタが注入される:

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

    @Autowired 
    UserDetailsService userDetailsService; 

    @Autowired 
    EntryPointUnauthorizedHandler unauthorizedHandler; 

    @Autowired 
    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception { 

     authenticationManagerBuilder 
          .userDetailsService(userDetailsService) 
          .passwordEncoder(passwordEncoder()); 
    } 

    @Bean 
    public PasswordEncoder passwordEncoder() { 

     return new BCryptPasswordEncoder(); 
    } 

    @Bean 
    @Override 
    public AuthenticationManager authenticationManager() throws Exception { 

     return super.authenticationManager(); 
    } 

    @Bean 
    public AuthenticationTokenFilter authenticationTokenFilter() throws Exception { 

     AuthenticationTokenFilter authenticationTokenFilter = new AuthenticationTokenFilter(); 
     authenticationTokenFilter.setAuthenticationManager(authenticationManager()); 

     return authenticationTokenFilter; 
    } 

    @Override 
    protected void configure(HttpSecurity httpSecurity) throws Exception { 

     httpSecurity 
      .csrf() 
       .disable() 
      .exceptionHandling() 
       .authenticationEntryPoint(unauthorizedHandler) 
       .and() 
      .sessionManagement() 
       .sessionCreationPolicy(SessionCreationPolicy.STATELESS) 
       .and() 
      .authorizeRequests() 
       .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() 
       .antMatchers("/auth/**").permitAll() 
       .anyRequest().authenticated(); 

     // filter injected here 
     httpSecurity.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class); 
    } 
} 

A場合をユーザーが期限切れのトークンを渡すと、次のエラーが表示されます。

{ 
    "timestamp":1496424964894, 
    "status":500, 
    "error":"Internal Server Error", 
    "exception":"com.app.exceptions.TokenExpiredException", 
    "message":"javax.servlet.ServletException: Token has expired", 
    "path":"/orders" 
} 

私は春のセキュリティが要求をコントローラ層に渡す前に傍受しているので、既存の@ControllerAdviceを使用してこれらの例外を処理することはできません。

ここで返されるエラーメッセージ/オブジェクトをカスタマイズするにはどうすればよいですか。他の場所では、エラーメッセージを返すためにJSON直列化POJOを使用しています。私もあなたに見せたくありません。javax.servlet.ServletException

答えて

1

.exceptionHandling()を使用しているので、新しいExceptionHandlerを設定することができます。

別の方法は、このように異なるメッセージを上書きすることです。post

関連する問題