从 https 切换到 http 时登录后 spring-boot 用户会话未添加到上下文中
Posted
技术标签:
【中文标题】从 https 切换到 http 时登录后 spring-boot 用户会话未添加到上下文中【英文标题】:spring-boot user session not added to context after login when switching from https to http 【发布时间】:2016-12-15 07:23:57 【问题描述】:我有一个 spring-boot 1.3.5.RELEASE 和 spring security 4.1.0.RELEASE 应用程序,用户在第一次输入用户名和密码后被重定向到登录页面。他们第二次输入用户名和密码时,它工作正常。
场景如下:
用户被重定向到登录页面(使用 HTTPS)
用户输入用户名和密码并回车
用户再次被重定向到登录页面,就好像他没有输入用户名和密码一样
用户再次输入用户名和密码并回车
用户被重定向到主页 (HTTP)
每次用户尝试登录时都会发生这种情况。
编辑:当我重新启动 spring-boot 应用程序或打开新的浏览器会话(chrome 人)时,不会发生这种情况。似乎只有在退出后才会发生
我追踪到 spring 的用户会话修复,但不知道如何修复。
我的配置是什么样子的:
@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:
@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();
我在调试过程中发现的:
在加载页面时,浏览器通过 HTTPS 重定向到 login
在用户输入用户名和密码并回车后,浏览器尝试通过 HTTPS 加载 defaultEntry
,然后通过 HTTP 重定向到 defaultEntry
。
我放置了一个过滤器和一个应用程序侦听器来跟踪正在发生的事情,我看到了以下内容
登录后按回车:
onApplicationEvent - 为用户验证会话:admin,sessionId:80CDEA048679E189485FE0F4597BE2E8
(TestFilter.java:34) 访问的 URL:https://localhost:8443/auth/login;当前用户:匿名
(TestFilter.java:34) 访问的 URL:https://localhost:8443/auth/login-secure;当前用户:匿名
(TestFilter.java:34) 访问的 URL:https://localhost:8443/auth/login-strings;当前用户:匿名
-
用户被重定向到通过 HTTP 登录,它重定向到通过 HTTPS 的安全登录
用户再次输入用户名和密码并回车
defaultEntry
现在直接通过 HTTP 加载(不再首先尝试通过 HTTPS)并加载主页
onApplicationEvent - 为用户验证会话:admin,sessionId:933F361668CFF01EBCC0DF88763D4DF4
(TestFilter.java:34) 访问的 URL:http://localhost:8000/defaultEntry;当前用户:CGSUserDetailsImplfirstName='admin', lastName='admin', email='admin@mycompany.com'
我也尝试更改 sessionFixation 模式和范围,但用户和授权在其他配置中不再自动装配。
我怎样才能让它第一次正确重定向到家?
【问题讨论】:
【参考方案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";
【讨论】:
以上是关于从 https 切换到 http 时登录后 spring-boot 用户会话未添加到上下文中的主要内容,如果未能解决你的问题,请参考以下文章
NSURLSessionDownloadTask 从 http 切换到 https
Grails 重定向控制器从 https 切换到 http。为啥?