学习Spring security过程中实现了remember-me的持久化实现(其实很简单的呀)
<remember-me key="elim" remember-me-parameter="remember-me"
token-validity-seconds="604800" data-source-ref="dataSource"
user-service-ref="customjdbcUserService" />
key属性的作用说实话不是很理解,token-validity-seconds表示remember-me的秒数,这里大概是7天吧。注意:remember-me本有两个版本,一个是inmemory,另外一个基于数据库。默认为inmemory实现,表示将凭证存储在内存中。重启服务器后凭证会消失,据说在集群中也不可用。但添加data-source-ref标签后,则自动激活数据库实现,表结构为:
(如果要自定义表结构,则需要实现***忘了)
之后实现了session的并发控制和防固化攻击,配置如下:
<session-management session-fixation-protection="migrateSession">
<concurrency-control max-sessions="1"
expired-url="/login?error=expired" />
</session-management>
<concurrency-control max-sessions="1"
expired-url="/login?error=expired" />
表示像QQ那样有人上线会把你顶下去。顶下去之后你再进行任何操作都会被重定向到/login?error=expired。
但问题来了,当在两个浏览器中登陆同一个账户时,发现第一个登陆的果然被顶下去了,第二个登陆的会话有效,但是如果此时重启服务器,会发现第二个登陆的用户的remember-me失效了,重现了几次之后发现确实是这个问题。继续看debug日志。
22:28:49,552 DEBUG FilterChainProxy:324 - / at position 2 of 16 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
22:28:49,552 DEBUG SecurityContextLogoutHandler:64 - Invalidating session: f9f57cm68yj11q4vcyzedjayw
22:28:49,552 DEBUG HttpSessionEventPublisher:88 - Publishing event: org.springframework.security.web.session.HttpSessionDestroyedEvent[source=org.eclipse.jetty.server.session.HashedSession:f9f57cm68yj11q4vcyzedjayw@1532245675]
22:28:49,553 DEBUG SessionRegistryImpl:167 - Removing session f9f57cm68yj11q4vcyzedjayw from principal's set of registered sessions
22:28:49,553 DEBUG PersistentTokenBasedRememberMeServices:407 - Logout of user guest
22:28:49,553 DEBUG PersistentTokenBasedRememberMeServices:346 - Cancelling cookie
22:28:49,554 DEBUG JdbcTemplate:908 - Executing prepared SQL update
22:28:49,554 DEBUG JdbcTemplate:627 - Executing prepared SQL statement [delete f