私は、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