У меня есть две защищенные области, для которых я предоставляю логины на основе форм.
Следующие работыкак и ожидалось:
- Перенаправление на страницу входа при доступе к защищенному ресурсу
- Перенаправление на страницу входа с параметром
?error
, когда учетные данные были ложными - Запрет доступак защищенному ресурсу на основе определенных ролей
Не работает следующее:
- Перенаправление на страницу входа после выхода из системы
При входе в системуout, я перенаправляю на /user/login?logout
для отображения сообщения «Вы вышли из системы», указывающего, что выход выполнен успешно. Однако это не работает, вместо этого перенаправление на /user/login?logout
перенаправляется на /user/login
, поэтому сообщение не отображается.
Когда я удаляю пользовательский обработчик выхода из системы .logoutSuccessHandler(logoutSuccessHandler())
и вместо этого включаю.logoutSuccessUrl("/user/login?logout").permitAll()
это работает!
Однако я хочу, чтобы этот обработчик выполнял дополнительные действия при выходе из системы.
@Configuration
@Order(1)
public static class FormLoginUser extends WebSecurityConfigurerAdapter {
@Bean
public AccessDeniedHandler accessDeniedHandler() {
return new UserCustomAccessDeniedHandler();
}
@Bean
public LogoutSuccessHandler logoutSuccessHandler() {
return new UserCustomLogoutSuccessHandler();
}
@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler() {
return new UserCustomAuthenticationSuccessHandler();
}
private AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> authenticationDetailsSource() {
return WebAuthenticationDetails::new;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/user/**")
.authorizeRequests().anyRequest().hasRole("USER")
.and()
.formLogin()
.loginPage("/user/login")
.permitAll()
.authenticationDetailsSource(authenticationDetailsSource())
.successHandler(authenticationSuccessHandler())
.and()
.logout()
.logoutUrl("/user/logout")
.logoutSuccessUrl("/user/login?logout").permitAll()
.logoutSuccessHandler(logoutSuccessHandler())
.and()
.exceptionHandling().accessDeniedHandler(accessDeniedHandler())
;
}
}
@Configuration
@Order(2)
public static class FormLoginAdmin extends WebSecurityConfigurerAdapter {
@Bean
public AccessDeniedHandler adminAccessDeniedHandler() {
return new AdminCustomAccessDeniedHandler();
}
@Bean
public LogoutSuccessHandler adminLogoutSuccessHandler() {
return new AdminCustomLogoutSuccessHandler();
}
@Bean
public AuthenticationSuccessHandler adminAuthenticationSuccessHandler() {
return new AdminCustomAuthenticationSuccessHandler();
}
private AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> authenticationDetailsSource() {
return WebAuthenticationDetails::new;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/admin/**")
.authorizeRequests().anyRequest().hasRole("ADMIN")
.and()
.formLogin()
.loginPage("/admin/login")
.authenticationDetailsSource(authenticationDetailsSource())
.successHandler(adminAuthenticationSuccessHandler())
.permitAll()
.and()
.logout()
.logoutUrl("/admin/logout")
.logoutSuccessHandler(adminLogoutSuccessHandler())
.and()
.exceptionHandling().accessDeniedHandler(adminAccessDeniedHandler());
}
}
Вот мой CustomLogoutHandler:
public class UserCustomLogoutSuccessHandler extends
SimpleUrlLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication)
throws IOException, ServletException {
this.setDefaultTargetUrl("/user/login?logout");
super.onLogoutSuccess(request, response, authentication);
}
}
ВDevTools, я ясно вижу, всякий раз, когда я пытаюсь получить доступ к URL /user/login?logout
, запрос GET приводит к 302, а затем делается новый запрос для user/login
. Это происходит, когда я вручную редактирую URL-адрес в строке URL-адреса браузера или когда запускаю выход через приложение FORM-Post из приложения.
Когда я удаляю logoutSuccessHandler
, я могу оба, ввести URL-адрес в браузере вручнуюи вызвать его из моего приложения FORM-Post в приложении.
Я также попытался:
- переместить URL-адреса для входа и выхода из системы из пути
/user
-> который сломал Логин - , определяя третью конфигурацию с
Order(1)
, явно разрешающим GET и POST на страницах входа и выхода из системы -> который также сломал Логин - не использует
.antMatcher
и использовать .antMatchers
вместо этого, однако тогда я думаю, что не смогу иметь два разных FormLogins