#spring-security
Вопрос:
Я пытаюсь обработать исключение проверки подлинности, вызванное в фильтре, реализует AbstractPreAuthenticatedProcessingFilter, как показано ниже.
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
if (authException instanceof UsernameNotFoundException) {
response.sendRedirect("https://myapp.com/signup");
}
if (authException instanceof CredentialsExpiredException) {
response.sendRedirect("https://myapp.com/update/password");
}
if (authException instanceof LockedException) {
response.sendRedirect("https://myapp.com/support/1");
}
if (authException instanceof DisabledException) {
response.sendRedirect("https://myapp.com/support/2");
}
if (authException instanceof AccountExpiredException) {
response.sendRedirect("https://myapp.com/update/account");
}
if (authException instanceof InsufficientAuthenticationException) {
System.out.println("#########InsufficientAuthenticationException########");
}
}
Каждое исключение, вызванное из
- UserDetailsChecker:https://github.com/spring-projects/spring-security/blob/006b9b960797d279b31cf8c8d16f1549c5632b2c/core/src/main/java/org/springframework/security/authentication/AccountStatusUserDetailsChecker.java
- UserDetailsService:https://github.com/spring-projects/spring-security/blob/006b9b960797d279b31cf8c8d16f1549c5632b2c/core/src/main/java/org/springframework/security/core/userdetails/AuthenticationUserDetailsService.java
Но каждый раз в моем тесте ловлю исключение недостаточной аутентификацииexception в моей точке аутентификации.
Это мой конфигуратор веб-безопасности.
@EnableWebSecurity
class MyWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/error");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/hello").hasRole("HELLO");
http.exceptionHandling().authenticationEntryPoint(new MyAuthenticationEntryPoint());
http.exceptionHandling().accessDeniedHandler(new MyAccessDeniedHandler());
http.addFilter(getMyPreAuthenticatedProcessingFilter());
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(getPreAuthenticatedAuthenticationProvider());
}
public AbstractPreAuthenticatedProcessingFilter getMyPreAuthenticatedProcessingFilter() throws Exception {
var myPreAuthenticatedProcessingFilter = new MyPreAuthenticatedProcessingFilter();
myPreAuthenticatedProcessingFilter.setAuthenticationManager(authenticationManager());
return myPreAuthenticatedProcessingFilter;
}
public PreAuthenticatedAuthenticationProvider getPreAuthenticatedAuthenticationProvider() {
var preAuthenticatedAuthenticationProvider = new PreAuthenticatedAuthenticationProvider();
preAuthenticatedAuthenticationProvider.setPreAuthenticatedUserDetailsService(new MyAuthenticationUserDetailsService());
return preAuthenticatedAuthenticationProvider;
}
}
My guess is
- Occur Exception in PreAuthenticatedProcessingFilter.
- Set AnonymousAuthenticationToken in SecurityContext since failed authentication setting in PreAuthenticatedProcessingFilter
- In FilterSecurityInterceptor, AnonymousAuthenticationToken is Denied and Keep AccessDeniedException in StackTrace
- In ExceptionTranslationFilter, start handling Exception (AccessDeniedException) as below
If an AccessDeniedException is detected, the filter will determine whether or not the user is an anonymous user. If they are an anonymous user, the authenticationEntryPoint will be launched. If they are not an anonymous user, the filter will delegate to the AccessDeniedHandler. By default the filter will use AccessDeniedHandlerImpl.
- Наконец, вызвал проверку подлинности Sendstart и переопределил тип исключения для исключения недостаточной проверки подлинности
Вопрос: Как определить тип исключения в AuthenticationEntryPoint ?
Я пытаюсь не использовать авторизованную конечную точку(и т. Д.»/world») с помощью AuthenticationFailureHandler, Успешно обнаруживаю тип исключения в фильтре предварительной проверки подлинности.
Но с разрешением я не уверен, как его обнаружить. Невозможно ли обнаружить тип исключения в точке проверки подлинности с авторизованной конечной точкой ?
http.authorizeRequests()
.antMatchers("/hello").hasRole("HELLO");
Комментарии:
1. Я не уверен, что понимаю. Если вы используете предварительную аутентификацию, то нет смысла улавливать такие вещи, как исключение DisabledException, поскольку аутентификация по определению выполнялась ранее.
2.
by definition, was performed previously.
Я знаю, что ты имеешь в виду. При условии, что MyPreAuthenticatedProcessingFilter был установлен AuthenticationFailureHandler, вышеуказанные Исключения могли обрабатываться, и HttpServletResponse мог совершать в них фиксацию. и если не AuthenticationFailureHandler, то вышеперечисленные Исключения, завернутые исключением недостаточной проверки подлинности, так как у SecurityContext нет функции AuthenticationToken.3. В первом случае с указанными выше исключениями фильтр предварительной обработки не смог сломать Последующий фильтр. так что, к сожалению, HttpServletResponse был подтвержден в AuthenticationEntryPoint, поскольку в SecurityContext нет аутентификации, затем выдайте ошибку 500, прежде чем возвращать HttpServletResponse.
Ответ №1:
«response.isCommited()» с условными условиями в каждом обработчике ошибок я решил эту проблему, спасибо за ваш ответ @jzhaux !