2016-05-10 5 views
3

Этот вопрос действительно связан с этой проблемой problem.Весна безопасности - Пользовательский ExceptionTranslationFilter

Основываясь на предложении @ harsh-poddar, я добавил фильтр соответственно.

Однако, добавив, что кажется, что я не могу войти даже с действительными учетными данными.

Ниже соответствующий код:

SecurityConfig

@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

// @Bean 
// public CustomAuthenticationEntryPoint customAuthenticationEntryPoint() { 
//  return new CustomAuthenticationEntryPoint(); 
// } 

@Bean 
public CustomExceptionTranslationFilter customExceptionTranslationFilter() { 
    return new CustomExceptionTranslationFilter(new CustomAuthenticationEntryPoint()); 
} 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
     //Note : Able to login without this filter, but after adding this, valid credential also fails 
     .addFilterAfter(customExceptionTranslationFilter(), ExceptionTranslationFilter.class) 
//  .exceptionHandling() 
//   .authenticationEntryPoint(new customAuthenticationEntryPoint()) 
//   .and() 
     .authorizeRequests() 
      .anyRequest().authenticated() 
      .and() 
     .requestCache() 
      .requestCache(new NullRequestCache()) 
      .and() 
     .httpBasic() 
      .and() 
     .csrf().disable(); 
} 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth.authenticationProvider(new CustomAuthenticationProvider()); 
    } 
} 

CustomAuthenticationProvider

@Component 
public class CustomAuthenticationProvider implements AuthenticationProvider { 

public CustomAuthenticationProvider() { 
    super(); 
} 

@Override 
public Authentication authenticate(final Authentication authentication) throws AuthenticationException { 
    final String name = authentication.getName(); 
    final String password = authentication.getCredentials().toString(); 
    if (name.equals("admin") && password.equals("password")) { 
     final List<GrantedAuthority> grantedAuths = new ArrayList<>(); 
     grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER")); 
     final UserDetails principal = new User(name, password, grantedAuths); 
     final Authentication auth = new UsernamePasswordAuthenticationToken(principal, password, grantedAuths); 
     return auth; 
    } else { 
     throw new BadCredentialsException("NOT_AUTHORIZED"); 
    } 
} 

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

} 

CustomExceptionTranslationFilter

@Component 
public class CustomExceptionTranslationFilter extends ExceptionTranslationFilter { 

    public CustomExceptionTranslationFilter(AuthenticationEntryPoint authenticationEntryPoint) { 
     super(authenticationEntryPoint); 
    } 
} 

CustomAuthenticationEntryPoint

public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { 

    @Override 
    public void commence(HttpServletRequest request, HttpServletResponse response, 
      AuthenticationException authException) throws IOException, ServletException { 
     response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized."); 
    } 
} 

р/с: простите за основной вопрос, я действительно новый весной & яровой безопасности.

+0

Смотрите мой ответ на вопрос Previos http://stackoverflow.com/questions/37063342/spring-security-with-restcontroller-jsonish-customauthenticationprovider-resp/37063583#37063583 – D0dger

+0

@ D0dger: спасибо за ответ данного. Но остается та же ошибка. Вход с действительными учетными данными также активирует «AuthExceptionEntryPoint». Любой подсказку, где я могу проверить, чтобы отладить это? – lxnx

+0

Включите ведение журнала для пакета 'org.springframework.security' и приложите его к вопросу (когда действительные учетные данные не работают) – D0dger

ответ

3

Предполагаемый дизайн для AuthenticationEntryPoint - это запуск/инициирование аутентификации. Однако ваша реализация CustomAuthenticationEntryPoint этого не делает. Вместо этого он просто отправляет обратно неавторизованный ответ. См. Javadoc для AuthenticationEntryPoint для получения дополнительной информации об особенностях реализации.

на основе конфигурации вы используете HTTP Basic для проверки подлинности:

protected void configure(HttpSecurity http) throws Exception { 
    http 
     .authorizeRequests() 
      .anyRequest().authenticated() 
      .and() 
     .httpBasic(); 
} 

Эта конкретная конфигурация автоматически настроит BasicAuthenticationEntryPoint который является реализация AuthenticationEntryPoint. BasicAuthenticationEntryPoint запросит у пользователя ответ HTTP-заголовка WWW-Authenticate: Basic realm="User Realm" для аутентификации, согласно server protocol.

Однако тот факт, что вы настраиваете свой собственный CustomAuthenticationEntryPoint, в конечном итоге переопределит BasicAuthenticationEntryPoint, который не является тем, что вы хотите сделать.

other post рекомендует эту конфигурацию, которая еще раз не то, что вы хотите сделать.

protected void configure(HttpSecurity http) throws Exception { 
    http 
     .authorizeRequests() 
      .anyRequest().authenticated() 
      .and() 
     .httpBasic() 
      .and() 
     .exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint()); 
} 

Если ваша главная цель состоит в том, чтобы предоставить собственный ответ пользователю при неудачной аутентификации, чем я хотел бы предложить конфигурацию формы входа в систему с настроенным AuthenticationFailureHandler.Вот конфигурация:

http 
    .authorizeRequests() 
     .anyRequest().authenticated() 
     .and() 
    .formLogin().failureHandler(new DefaultAuthenticationFailureHandler()) 
     .and() 
    .csrf().disable(); // NOTE: I would recommend enabling CSRF 

Ваша реализация DefaultAuthenticationFailureHandler будет:

public class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandler { 

    @Override 
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { 
     // Set status only OR do whatever you want to the response 
     response.setStatus(HttpServletResponse.SC_FORBIDDEN); 
    } 
} 

AuthenticationFailureHandler специально разработан для обработки неудачной попытки аутентификации.

+0

благодарит за предложение. Я пробовал это и обнаружил, что каждый запрос был перенаправлен (302) на «/ login». Для вашей информации это веб-сервис, связанный через @RestController. – lxnx

Смежные вопросы