У меня есть приложение spring -boot 1.3.5.RELEASE с приложением Spring security 4.1.0.RELEASE, и пользователи перенаправляются на страницу входа после первого ввода имени пользователя и пароля. Во второй раз, когда они вводят имя пользователя и пароль, все работает нормально.
Сценарий такой:
пользователи перенаправляются на страницу входа (которая использует HTTPS)
пользователь вводит имя пользователя и пароль и нажимает клавишу ВВОД
пользователь снова перенаправляется на страницу входа, как если бы он не вводил имя пользователя и пароль
пользователь снова вводит имя пользователя и пароль и нажимает клавишу ВВОД
пользователь перенаправляется на домашнюю страницу (HTTP)
Это происходит каждый раз, когда пользователь пытается войти в систему.
Изменить: этого не происходит, когда я перезапускаю приложение с весенней загрузкой или когда открываю новый сеанс браузера (хромированный человек). Похоже, это происходит только после выхода.
Я отследил это до весенней фиксации сеанса пользователя, но не знаю, как это исправить.
Как выглядит моя конфигурация:
@Override
public void configure(HttpSecurity http) throws Exception {
http
.headers().disable()
.csrf().disable()
.formLogin()
.loginPage("/auth/login")
.loginProcessingUrl("/auth/login")
.failureUrl("/auth/login-secure?loginFailed=true")
.defaultSuccessUrl("/defaultEntry")
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutUrl("/auth/logout")
.logoutSuccessUrl("/auth/logout-success")
.deleteCookies("jsessionid", "JSESSIONID")
.and()
.sessionManagement().sessionFixation().none()
.and()
.anonymous().principal(ANONYMOUS_USER)
.and()
.authorizeRequests()
.antMatchers("/websocket/**").authenticated()
.antMatchers("/auth/login", "/auth/login-secure", "/auth/login-oauth2").permitAll()
.antMatchers("/auth/external-logout").authenticated()
.antMatchers("/index.jsp").permitAll()
.antMatchers("/defaultEntry").authenticated()
.antMatchers("/admin/**/*").hasRole("T2K_ADMIN")
.antMatchers("/client/**/*").authenticated();
// we set the redirect port for https for dev environment. Production environment has the connectors configured in Tomcat's server.xml
if (Arrays.asList(environment.getActiveProfiles()).contains(SpringProfiles.DEVELOPMENT)) {
http.portMapper()
.http(Integer.parseInt(environment.getProperty("server.port")))
.mapsTo(Integer.parseInt(environment.getProperty("server.https.port")));
}
http.requiresChannel()
.antMatchers("/auth/**").requiresSecure()
.anyRequest().requiresInsecure();
}
Контроллер:
@Controller
public class HomeController {
@Autowired
private CGSUserDetails currentUser;
@Autowired
private Authentication authentication;
@RequestMapping(value = "/auth/login", method = RequestMethod.GET)
public String login() {
return "redirect:login-secure";
}
@RequestMapping(value = "/auth/login-secure", method = RequestMethod.GET)
public String loginSecure() {
if (authentication.isAuthenticated() && !ANONYMOUS_USER.equals(authentication.getName())) {
return "redirect:/defaultEntry";
} else {
return "auth/login"; // get /auth/login.jsp
}
}
@RequestMapping(value = {"/home"}, method = RequestMethod.GET)
public String openHomePage() throws Exception {
if (authentication.isAuthenticated() && !ANONYMOUS_USER.equals(authentication.getName())) {
return "index";
} else {
return "redirect:/defaultEntry";
}
}
@RequestMapping(value = "/defaultEntry", method = RequestMethod.GET)
public String defaultEntry() {
if (authentication.isAuthenticated() && !ANONYMOUS_USER.equals(authentication.getName())) {
return "redirect:/home";
} else {
return "redirect:login";
}
}
}
Бины пользователя и аутентификации:
@Bean(name = "userDetails")
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public UserDetails userDetails() {
return AuthenticationHolder.getUserDetails();
}
@Bean(name = "authentication")
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public Authentication authentication() {
return AuthenticationHolder.getAuthentication();
}
Что выяснил во время отладки:
При загрузке страницы браузер перенаправляет на
login
через HTTPSПосле того, как пользователь вводит имя пользователя и пароль и нажимает клавишу ВВОД, браузер пытается загрузить
defaultEntry
через HTTPS, а затем перенаправляется наdefaultEntry
через HTTP. Я устанавливаю фильтр и прослушиватель приложения, чтобы отслеживать, что происходит, и после нажатия клавиши ввода при входе в систему вижу следующее:
onApplicationEvent - сеанс аутентифицирован для пользователя: admin, sessionId: 80CDEA048679E189485FE0F4597BE2E8
(TestFilter.java:34) Доступ к URL: https://localhost:8443/auth/login; Текущий пользователь: Annonymous
(TestFilter.java:34) Доступ к URL: https: // localhost: 8443 / auth / login-secure а>; Текущий пользователь: Annonymous
(TestFilter.java:34) Доступ к URL: https: // localhost: 8443 / auth / login-strings а>; Текущий пользователь: Annonymous
- Пользователь был перенаправлен на вход через HTTP, который перенаправляет на безопасный вход через HTTPS.
- Пользователь снова вводит имя пользователя и пароль и нажимает клавишу ВВОД.
defaultEntry
теперь загружается напрямую через HTTP (больше не нужно пробовать сначала через HTTPS), а домашняя страница загружается.
onApplicationEvent - сеанс аутентифицирован для пользователя: admin, sessionId: 933F361668CFF01EBCC0DF88763D4DF4
(TestFilter.java:34) Доступ к URL: http://localhost:8000/defaultEntry; Текущий пользователь: CGSUserDetailsImpl {firstName = 'admin', lastName = 'admin', email='[email protected] '}
Я также попытался изменить режим и область действия sessionFixation, но пользователь и авторизация больше не были подключены автоматически в другой конфигурации.
Как я могу сделать так, чтобы он правильно перенаправлялся домой в первый раз?