Spring Security — как перехватить исключение аутентификации от пользовательского поставщика аутентификации

#spring #spring-security

#spring #spring-безопасность

Вопрос:

Я пытаюсь перехватить и настроить исключение аутентификации, созданное в настраиваемом фильтре аутентификации, но как только генерируется исключение, оно всегда переходит к классу provider manager и отправляет ответ об ошибке spring API по умолчанию.

  1. Класс конфигурации WebSecurity
 @Configuration

public static class RestAPISecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    AuthenticationEntry authenticationEntryPoint;

    @Autowired
    BasicAuthenticationProvider customAuthProvider;

    @Autowired
    AuthenticationFailureHandler accessDeniedHandler;

    private final RequestMatcher PROTECTED_URLS = new OrRequestMatcher(
            new AntPathRequestMatcher(API_PATH_IDENTIFIER));

    @Value("${username}")
    private String userName;

    @Value("${password}")
    private String password;

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.authenticationProvider(customAuthProvider);
        auth.inMemoryAuthentication().withUser("abcd").password(passwordEncoder().encode("sample@123"))
                .roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests().antMatchers("/api")
                .authenticated().and().exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers(SECURITY_EXCLUDED_PATHS);
    }

}
 

Класс AuthenticationProvider:

 
@Component
public class BasicAuthenticationProvider implements AuthenticationProvider {
    
    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver resolver;
    
    @Override
    public Authentication authenticate(Authentication auth) throws UserAuthenticationException
      {
        String username = auth.getName();
        String password = auth.getCredentials()
            .toString();
        AuthenticationException exception = null;
        
        
        try {

        if ("abcd".equals(username) amp;amp; "Sample@123".equals(password)) {
            return new UsernamePasswordAuthenticationToken
              (username, password, Collections.emptyList());
        } else {
            
           throw new BadCredentialsException("invalid user");
           
        }
        
        
    }catch(AuthenticationException e)
        {
         exception = e;

         throw exception;
         
        }
      }

    @Override
    public boolean supports(Class<?> auth) {
        return auth.equals(UsernamePasswordAuthenticationToken.class);
    }

    
}
 

Класс AuthenticationEntryPoint:

 
/**
 *
 * Authentication entry point to handle security exceptions
 *
 */
@Component
public class AuthenticationEntry implements AuthenticationEntryPoint{
    
    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver resolver;
    
    /**
     *This handles security exceptions and redirects it to exception handler
     */
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws UserAuthenticationException {
        httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
        resolver.resolveException(httpServletRequest, httpServletResponse, null, new UserAuthenticationException("Not Authorized"));
    }

}
 

Комментарии:

1. Вы не должны. Что вы хотите настроить?

2. Текущая реализация отправляет следующий ответ об ошибке:

3. Я хочу настроить приведенный выше ответ на удобное для пользователя сообщение

4. Затем создайте исключение с соответствующим сообщением или предоставьте лучшее сообщение для обеспечения правильного сопоставления этой ошибки с сообщением через инфраструктуру I18N.

5. да, я могу изменить сообщение об ошибке, но у меня есть ответ об ошибке по умолчанию для всех несанкционированных запросов в моем приложении. Я хочу отправить что-то вроде приведенного ниже, {«статус»: «сбой», «сообщение»: «Вам не разрешен доступ к этому API»)

Ответ №1:

вы можете создать исключение в цепочке фильтров

Комментарии:

1. Пожалуйста, постарайтесь быть более наглядным в своем объяснении. В дополнение к добавлению кода в качестве ответа попробуйте добавить краткое объяснение того, почему это удобно.

2. пожалуйста, объясните подробно