Обработка ошибок авторизации при отключении службы авторизации в Spring boot security не работает

#spring #spring-boot #spring-security

#spring #spring-boot #spring-security

Вопрос:

В моем веб-приложении spring boot я обращаюсь за авторизацией к сторонней службе, а мое приложение является всего лишь поставщиком контента. Родительское приложение использует site minder для аутентификации. Мое приложение получает идентификатор пользователя в заголовке и вызывает сторонний API для настройки пользовательских данных с полномочиями.

Мое требование — обработать сценарий, когда сторонняя служба авторизации отключена. В настоящее время в этом случае я устанавливаю пользовательские параметры без ролей, и поскольку каждая конечная точка привязана к авторизации, я получаю 403, если сторонняя служба авторизации отключена.

Но я хочу отобразить другое сообщение, если пользователю не хватает авторизации и если служба авторизации отключена.

Если я обрабатываю отключение службы авторизации путем создания пользовательского исключения из UserDetailsServiceImpl -> loadUserByUsername(), тогда RequestHeaderAuthenticationFilter обнаруживает это исключение, и запрос отфильтровывается. Есть идеи, как это сделать?

SecurityConfiguration

 public class WebSecurityCustomConfig extends WebSecurityConfigAdapter {
 private UserDetailsService userDetails;
 protected void configure(HttpSecurity http) {
   http.csrf().disable().authorizeRequests().antMatchers("/*).permitAll()
   .anyRequests()
   .hasAnyAuthority("MODULEX","MODULEY");

 http.addFilterBefore(requestHeaderAuthFilter(), 
   BasicAuthenticationFilter.class);
    http.exceptionHandling().authenticationEntryPoint(customEntryPoint());
 }

 protect void configure(AuthenticationManagerBuilder builder) {
   PreAuthenticaticatedAuthenticationProvider auth = new 
             PreAuthenticaticatedAuthenticationProvider ();
  auth.setPreAuthenticatedUserDetailsService(new 
      UserDetailsByNameServiceWrapper<>(userDetails));
  }
 }
  

Пользовательский UserDetailsService

   public class CustomUserDetailsService implements UserDetailsService {
    private final AuthorizationService authService;
    @Inject
     public CustoUserDetailsService(AuthorizationService authService) {
       this.authService = authService;
       }
       public UserDetails loadUserByUsername(String username) {
         return new User(username, "", 
                 authService.getAuthorities(username));  
        // authService is a  third party jar and if their upstream service 
           //is down , it throws a runtime exception
      }
      }
  

Если я обработаю их ошибку следующим образом, то в итоге получу 403, но я хочу 503 в случае, если служба отключена, и 403, если у пользователя нет правильных полномочий для конечной точки, к которой он обращается.

текущая обработка исключения службы авторизации

      public UserDetails loadUserByUsername(String username) {
         try{
         return new User(username, "", 
                 authService.getAuthorities(username));  
       }
          catch(AuthServiceException e) {
               return new User(username, "", 
                 Collections.emptyList());  
               } 
      }
  

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

1. Если я создаю исключение из userdetailsservice вместо обработки, то оно не попадает в CustomauthenticationEntryPoint, который можно использовать для получения соответствующего ответа в случае отключения службы

2. в приведенной выше реализации пользователь без полномочий и при авторизации видит ту же ошибку, которая неверна

Ответ №1:

Реализуйте AuthenticationEntryPoint и переопределяйте commence() метод следующим образом.

 public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(
            HttpServletRequest request, 
            HttpServletResponse response, 
            AuthenticationException authException) throws IOException, ServletException {

        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");

    }

}
  

И после этого создайте в своем WebSecurityCustomConfig классе метод, который инициализирует RestAuthenticationEntryPoint класс следующим образом.

 public AuthenticationEntryPoint authenticationEntryPoint() {
    RestAuthenticationEntryPoint ep = new RestAuthenticationEntryPoint();
    return ep;
}
  

Затем измените следующую строку на http.exceptionHandling().authenticationEntryPoint(customEntryPoint());

Для
http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint());