我的身份验证基于
spring-boot-security-example.
当我输入无效令牌时,我想抛出401 Unauthorized异常.但是,我总是找不到404资源.我的配置设置了一个异常处理,但它被忽略 – 可能是因为之前添加了我的AuthenticationFilter而请求没有到达我的异常处理程序.
当我输入无效令牌时,我想抛出401 Unauthorized异常.但是,我总是找不到404资源.我的配置设置了一个异常处理,但它被忽略 – 可能是因为之前添加了我的AuthenticationFilter而请求没有到达我的异常处理程序.
我需要改变什么才能抛出401异常?
我有一个身份验证过滤器:
public class AuthenticationFilter extends GenericFilterBean { ... @Override public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException { HttpServletRequest httpRequest = asHttp(request); HttpServletResponse httpResponse = asHttp(response); Optional<String> token = Optional.fromNullable(httpRequest.getHeader("X-Auth-Token")); try { if (token.isPresent()) { logger.debug("Trying to authenticate user by X-Auth-Token method. Token: {}",token); processTokenAuthentication(token); addSessionContextToLogging(); } logger.debug("AuthenticationFilter is passing request down the filter chain"); chain.doFilter(request,response); } catch (InternalAuthenticationServiceException internalAuthenticationServiceException) { SecurityContextHolder.clearContext(); logger.error("Internal authentication service exception",internalAuthenticationServiceException); httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } catch (AuthenticationException authenticationException) { SecurityContextHolder.clearContext(); httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,authenticationException.getMessage()); } finally { MDC.remove(TOKEN_SESSION_KEY); MDC.remove(USER_SESSION_KEY); } } private void addSessionContextToLogging() { ... } ... private void processTokenAuthentication(Optional<String> token) { Authentication resultOfAuthentication = tryToAuthenticateWithToken(token); SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication); } private Authentication tryToAuthenticateWithToken(Optional<String> token) { PreAuthenticatedAuthenticationToken requestAuthentication = new PreAuthenticatedAuthenticationToken(token,null); return tryToAuthenticate(requestAuthentication); } private Authentication tryToAuthenticate(Authentication requestAuthentication) { Authentication responseAuthentication = authenticationManager.authenticate(requestAuthentication); if (responseAuthentication == null || !responseAuthentication.isAuthenticated()) { throw new InternalAuthenticationServiceException("Unable to authenticate Domain User for provided credentials"); } logger.debug("User successfully authenticated"); return responseAuthentication; }
AuthenticationProvider实现:
@Provider public class TokenAuthenticationProvider implements AuthenticationProvider { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { Optional<String> token = (Optional) authentication.getPrincipal(); if (!token.isPresent() || token.get().isEmpty()) { throw new BadCredentialsException("No token set."); } if (!myCheckHere()){ throw new BadCredentialsException("Invalid token"); } return new PreAuthenticatedAuthenticationToken(myConsumerObject,null,AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_API_USER")); } ... }
以及如下配置:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http. csrf().disable(). sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS). and(). anonymous().disable(). exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint()); http.addFilterBefore(new AuthenticationFilter(authenticationManager()),BasicAuthenticationFilter.class); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(tokenAuthenticationProvider()); } @Bean public AuthenticationProvider tokenAuthenticationProvider() { return new TokenAuthenticationProvider(); } @Bean public AuthenticationEntryPoint unauthorizedEntryPoint() { return (request,response,authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } }
解决方法
我在这个帖子中找到了答案:
Return HTTP Error 401 Code & Skip Filter Chains
代替
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,authenticationException.getMessage());
我需要打电话
httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);