Http协议是一种无状态协议所以当服务端需要记录用户的状态时,需要某种机制用于识别用户,这个机制就是Session。服务器通过和用户约定每一个请求携带一个id信息,用于统一用户的请求有了管理,并且区分不同用户。基于session方案,为让用户请求都携带同一个id,并且不妨碍用户体验的情况下,选择Cookie作为载体是一个不错的选择,用户第一次访问服务器的时候,没有携带id,服务器端会生成sessionid:session键值对,并且发送sessionid给客户端添加到cookie中。然后该用户在之后的访问中,每一次请求都会将sessionid放到cookie中,使得服务端可以很容易识别用户。
但是有时候用户为了保护个人信息或者安全考虑会禁用cookie,这时候cookie就无法使用。因此有时候服务还支持用url重写来实现,比如:
http://www.baidu.com;jessionid=xxx
URL重写原本是为了兼容禁用cookie的浏览器而设计的,但也容易被黑客利用。黑客只需访问一 次系统,将系统生成的sessionId提取并拼凑在URL上,然后将该URL发给一些取得信任的用户。只要 用户在session有效期内通过此URL进行登录,该sessionId就会绑定到用户的身份,黑客便可以轻松享 有同样的会话状态,完全不需要用户名和密码,这就是典型的会话固定攻击。
防御会话固定攻击
sessionManagement是一个会话管理的配置器,其中,防御会话固定攻击的策略有四种:
- none:用户登录后session不发生变化
- newSession:用户登录以后创建新的session
- migrateSession:用户登录后创建新的session,但是会将旧的session中数据复制到新的session中。
- changeSessionId:不创建新的会话,而是使用selert容器提供的会话固定保护,每次登录访问之后都更换sessionid,但是没有新建session会话。默认启动此策略
http.sessionManagement().sessionFixation().changeSessionId();
除了防御会话固定攻击,还可以通过springSecurity配置会话过期策略,比如会话过期跳转到某个URL。在Springboot应用中有两种会话超时设置的方式,当会话超时之后用户需要重写登录才可以访问应用:
- server.servlet.session.timeout=1m
- spring.session.timeout=1m
方式1是springboot应用自带的session超时设置,方式2是使用Spring Session之后。提供的session超时配置,方式2优先级高。
在Spring Boot中Session超时最短的时间是一分钟,当你的设置小于一分钟的时候,默认为一分钟默认超时时长是30分钟
默认情况下session失效以后会跳转到认证页面,我们可以自定义session失效后,响应结果,有以下两种方式。
invalidSessionUrlinvalidSessionUrl作用是session失效后跳转的url,配置如下,在安全配置中心的 configure(HttpSecurity http)方法中添加代码如下:
- 在src\main\resources\templates路径下添加invalidSession.html
<!--suppressALL-->
<!DOCTYPEhtml>
<htmlxmlns:th="http://www.thymeleaf.org"lang="en">
<head>
<metacharset="utf-8">
<metahttp-equiv="X-UA-Compatible"content="IE=edge">
<title>springboot葵花宝典登录页面</title>
<!--Tellthebrowsertoberesponsivetoscreenwidth-->
<metaname="viewport"content="width=device-width,initial-scale=1">
</head>
<body>
<h1>springboot葵花宝典登录页面</h1>
<h2>session会话失效</h2>
</body>
</html>
- 在controller中添加
@RequestMapping("/invalidSession")
publicStringinvalidSession(){
return"invalidSession";//classpath:/templates/login.html
}
- 在LearnSrpingSecurity的configure(HttpSecurity http)添加配置
http.sessionManagement().invalidSessionUrl("/invalidSession")
具体配置如图
注意要以上路径需要配置permitAll()权限,即无需授权即可访问
测试启动项目登录后,再次登录,结果如下
invalidSessionStrategy
session失败后的策略,配置如下:
- 创建com.security.learn.sessionStrategy.CustomInvalidSessionStrategy代码如下
publicclassCustomInvalidSessionStrategyimplementsInvalidSessionStrategy{
privatestaticObjectMapperobjectMapper=newObjectMapper();
@Override
publicvoidonInvalidSessionDetected(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException,ServletException{
Cookiecookie=newCookie("JSESSIONID",null);
cookie.setMaxAge(0);
StringcontextPath=request.getContextPath();
Stringc=contextPath.length()>0?contextPath:"/";
cookie.setPath(c);
response.addCookie(cookie);
//当认证失败后,响应JSON数据给前端
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString("策略失效"));
}
}
- 将CustomInvalidSessionStrategy注入容器
@Configuration
publicclassMyconfig{
@Bean
@ConditionalOnMissingBean(InvalidSessionStrategy.class)
publicCustomInvalidSessionStrategycustomInvalidSessionStrategy(){
returnnewCustomInvalidSessionStrategy();
}
}
- 添加session失效处理
在LearnSrpingSecurity的configure(HttpSecurity http)添加配置,代码如下
测试
启动项目登录后,再次登录,结果如下
如果您觉得本文不错,欢迎关注,点赞,收藏支持,您的关注是我坚持的动力!
公众号 springboot葵花宝典 主要分享JAVA技术,主要包含SpringBoot、SpingCloud、Docker、中间件等技术
原创不易,转载请注明出处,感谢支持!如果本文对您有用,欢迎转发分享!
,