java – Spring Boot Security不会抛出401 Unauthorized Exception,但404 Not Found

前端之家收集整理的这篇文章主要介绍了java – Spring Boot Security不会抛出401 Unauthorized Exception,但404 Not Found前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的身份验证基于 spring-boot-security-example.
当我输入无效令牌时,我想抛出401 Unauthorized异常.但是,我总是找不到404资源.我的配置设置了一个异常处理,但它被忽略 – 可能是因为之前添加了我的AuthenticationFilter而请求没有到达我的异常处理程序.

我需要改变什么才能抛出401异常?

我有一个身份验证过滤器:

  1. public class AuthenticationFilter extends GenericFilterBean {
  2.  
  3. ...
  4.  
  5. @Override
  6. public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException {
  7. HttpServletRequest httpRequest = asHttp(request);
  8. HttpServletResponse httpResponse = asHttp(response);
  9. Optional<String> token = Optional.fromNullable(httpRequest.getHeader("X-Auth-Token"));
  10.  
  11. try {
  12. if (token.isPresent()) {
  13. logger.debug("Trying to authenticate user by X-Auth-Token method. Token: {}",token);
  14. processTokenAuthentication(token);
  15. addSessionContextToLogging();
  16. }
  17.  
  18. logger.debug("AuthenticationFilter is passing request down the filter chain");
  19. chain.doFilter(request,response);
  20. } catch (InternalAuthenticationServiceException internalAuthenticationServiceException) {
  21. SecurityContextHolder.clearContext();
  22. logger.error("Internal authentication service exception",internalAuthenticationServiceException);
  23. httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  24. } catch (AuthenticationException authenticationException) {
  25. SecurityContextHolder.clearContext();
  26. httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,authenticationException.getMessage());
  27. } finally {
  28. MDC.remove(TOKEN_SESSION_KEY);
  29. MDC.remove(USER_SESSION_KEY);
  30. }
  31. }
  32.  
  33. private void addSessionContextToLogging() {
  34. ...
  35. }
  36.  
  37. ...
  38.  
  39. private void processTokenAuthentication(Optional<String> token) {
  40. Authentication resultOfAuthentication = tryToAuthenticateWithToken(token);
  41. SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication);
  42. }
  43.  
  44. private Authentication tryToAuthenticateWithToken(Optional<String> token) {
  45. PreAuthenticatedAuthenticationToken requestAuthentication = new PreAuthenticatedAuthenticationToken(token,null);
  46. return tryToAuthenticate(requestAuthentication);
  47. }
  48.  
  49. private Authentication tryToAuthenticate(Authentication requestAuthentication) {
  50. Authentication responseAuthentication = authenticationManager.authenticate(requestAuthentication);
  51. if (responseAuthentication == null || !responseAuthentication.isAuthenticated()) {
  52. throw new InternalAuthenticationServiceException("Unable to authenticate Domain User for provided credentials");
  53. }
  54. logger.debug("User successfully authenticated");
  55. return responseAuthentication;
  56. }

AuthenticationProvider实现:

  1. @Provider
  2. public class TokenAuthenticationProvider implements AuthenticationProvider {
  3.  
  4. @Override
  5. public Authentication authenticate(Authentication authentication) throws AuthenticationException {
  6. Optional<String> token = (Optional) authentication.getPrincipal();
  7. if (!token.isPresent() || token.get().isEmpty()) {
  8. throw new BadCredentialsException("No token set.");
  9. }
  10. if (!myCheckHere()){
  11. throw new BadCredentialsException("Invalid token");
  12. }
  13.  
  14. return new PreAuthenticatedAuthenticationToken(myConsumerObject,null,AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_API_USER"));
  15. }
  16.  
  17. ...
  18.  
  19. }

以及如下配置:

  1. @Configuration
  2. @EnableWebSecurity
  3. @EnableGlobalMethodSecurity(prePostEnabled = true)
  4. public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  5.  
  6. @Override
  7. protected void configure(HttpSecurity http) throws Exception {
  8. http.
  9. csrf().disable().
  10. sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
  11. and().
  12. anonymous().disable().
  13. exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint());
  14.  
  15. http.addFilterBefore(new AuthenticationFilter(authenticationManager()),BasicAuthenticationFilter.class);
  16. }
  17.  
  18.  
  19. @Override
  20. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  21. auth.authenticationProvider(tokenAuthenticationProvider());
  22. }
  23.  
  24.  
  25. @Bean
  26. public AuthenticationProvider tokenAuthenticationProvider() {
  27. return new TokenAuthenticationProvider();
  28. }
  29.  
  30. @Bean
  31. public AuthenticationEntryPoint unauthorizedEntryPoint() {
  32. return (request,response,authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
  33. }
  34. }

解决方法

我在这个帖子中找到了答案: Return HTTP Error 401 Code & Skip Filter Chains

代替

  1. httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,authenticationException.getMessage());

我需要打电话

  1. httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

当我不继续调用它并将状态设置为不同的代码时,链似乎会停止 – 异常被正确抛出

猜你在找的Java相关文章