今天把登录页面再完善一下,主要完成一下两个功能:注销和自动登录。
1.注销功能
注销功能很简单,只要将请求提交到j_spring_security_logout即可。
<a href="j_spring_security_logout">注销</a>
可以在applicationContext-security.xml中配置
<logout logout-success-url="/login.jsp" />
定义注销后返回的页面。
2.自动登录功能
有两种方式可以实现记住用户的能力。一种做法是利用浏览器端的 cookie。当用户成功登录之后,特定内容的字符串被保存到 cookie 中。下次用户再次访问的时候,保存在 cookie 中的内容被用来认证用户。默认情况下使用的是这种方式。使用 cookie 的做法存在安全隐患,比如攻击者可能窃取用户的 cookie,并用此 cookie 来登录系统。另外一种更安全的做法是浏览器端的 cookie 只保存一些随机的数字,而且这些数字只能使用一次,在每次用户登录之后都会重新生成。这些数字保存在服务器端的数据库中。如果希望使用这种方式,需要创建 一个数据库表,并通过 data-source-ref
属性来指定包含此表的数据源。
1)在数据可当中添加一张表
create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, token varchar(64) not null, last_used timestamp not null)
2)修改applicationContext-security.xml
在<http>当中添加
<remember-me data-source-ref="dataSource"/>
3)在登录页面中添加
<input type='checkbox' name='_spring_security_remember_me'/>两周内自动登录<br>
需要注意的问题:
1)对于firefox等多页面浏览器,在一个firefox进程中打开一个页面后关闭再打开,session信息仍然不变,容易造成没有添加<remember-me>发现也能自动登录的现象。
2)当点击注销后,服务器将删除存放在数据库当中的用户信息,自动登录将失效。
3)多个浏览器同时登录将导致服务器在数据库中存放多条登录信息,导致自动登录失效,并出现This session has been expired (possibly due to multiple concurrent logins being attempted as the same user 错误信息,解决方法是限制同一个用户只能有一个session信息。
<session-management> <concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/> </session-management>
这样做有一个缺点:如果有人登陆的时候因为某些问题没有进行logout就退出了系统,那么他只能等到session过期自动销毁之后,才能再次登录系统。