Сессия пользователя spring -boot не добавляется в контекст после входа в систему при переключении с https на http

У меня есть приложение spring -boot 1.3.5.RELEASE с приложением Spring security 4.1.0.RELEASE, и пользователи перенаправляются на страницу входа после первого ввода имени пользователя и пароля. Во второй раз, когда они вводят имя пользователя и пароль, все работает нормально.

Сценарий такой:

  1. пользователи перенаправляются на страницу входа (которая использует HTTPS)

  2. пользователь вводит имя пользователя и пароль и нажимает клавишу ВВОД

  3. пользователь снова перенаправляется на страницу входа, как если бы он не вводил имя пользователя и пароль

  4. пользователь снова вводит имя пользователя и пароль и нажимает клавишу ВВОД

  5. пользователь перенаправляется на домашнюю страницу (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();
}

Что выяснил во время отладки:

  1. При загрузке страницы браузер перенаправляет на login через HTTPS

  2. После того, как пользователь вводит имя пользователя и пароль и нажимает клавишу ВВОД, браузер пытается загрузить 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

  1. Пользователь был перенаправлен на вход через HTTP, который перенаправляет на безопасный вход через HTTPS.
  2. Пользователь снова вводит имя пользователя и пароль и нажимает клавишу ВВОД.
  3. defaultEntry теперь загружается напрямую через HTTP (больше не нужно пробовать сначала через HTTPS), а домашняя страница загружается.

onApplicationEvent - сеанс аутентифицирован для пользователя: admin, sessionId: 933F361668CFF01EBCC0DF88763D4DF4

(TestFilter.java:34) Доступ к URL: http://localhost:8000/defaultEntry; Текущий пользователь: CGSUserDetailsImpl {firstName = 'admin', lastName = 'admin', email='[email protected] '}

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

Как я могу сделать так, чтобы он правильно перенаправлялся домой в первый раз?


person Alex Burdusel    schedule 09.08.2016    source источник


Ответы (1)


Хорошо, я исправил. В моем случае проблема была вызвана формой выхода.

@RequestMapping(value = "/auth/logout-success", method = RequestMethod.GET)
public String logoutSuccess() {
    return "auth/logout-success";
}

Это загружало следующий .jsp

<head>
    <title>Logout</title>
</head>
<body>
    <script type="text/javascript">
        window.location = "login";
    </script>
</body>

Я удалил этот .jsp и изменил отображение выхода из системы на:

@RequestMapping(value = "/auth/logout-success", method = RequestMethod.GET)
public String logoutSuccess() {
    return "redirect:/defaultEntry";
}
person Alex Burdusel    schedule 09.08.2016