场景:
1-打开一个Tab,用Admin登录系统
2-再打开一个Tab,用User登录系统
3-退回Admin的Tab,操作数据
此时的用户已经不是Admin而是User了。
※早期主流浏览器没有选项卡,开创选项卡浏览器的是国人二次开发的MyIE。
不理解Session与Cookie的先补补这部分知识。
[img]http://dl2.iteye.com/upload/attachment/0115/6757/ff90d33c-2e12-3a10-a6d9-6c0cea7ca7f6.png[/img]
浏览器的多选项卡之间是共有一个Session的,所以这种情况下一般需要通过以下方法来访问系统:
1)打开不同的浏览器,比如:IE、FF、Chrome
2)打开同一浏览器的多个窗口(不是Ctrl+N打开)
IE: File>New Session
FF: File>New Private Window(Ctrl+Shift+P)
Chrome: Menu>New incognito Window(Ctrl+Shift+N)
这两种方法只能针对开发测试的,对用户来说就有些牵强了。
如何让系统支持多用户在多选项卡间同时登陆?首先最基本的需要采用ACL权限控制来保证用户的权限不会越级,比如上边这个场景不至于普通User执行了Admin的操作。
其次需要让多个选项卡之间只允许一个用户登录。
1)过滤请求,如果访问的是登录页,查看Session中是否已有用户信息,直接跳向指定页。
2)成功登陆后新建一个会话,删除老的会话,可防御会话劫持Session Fixation / Hijacking。
另外两个问题:
1)限制同一个用户在同一时间只能登录一次
这里说的不是SSO单点登录,而是防止一个账户多处登录
在服务器端存储一个User的会话Map<User, Session>(或存入DB)
创建一个HttpSessionListener来监听会话,如果该User的会话已经存在用新的会话替换它。
2)同一服务器多应用的会话管理
Tomcat使用JSESSIONID作为默认的Cookie键值来识别Session,也可以自定义该键值:
1-打开一个Tab,用Admin登录系统
2-再打开一个Tab,用User登录系统
3-退回Admin的Tab,操作数据
此时的用户已经不是Admin而是User了。
※早期主流浏览器没有选项卡,开创选项卡浏览器的是国人二次开发的MyIE。
不理解Session与Cookie的先补补这部分知识。
[img]http://dl2.iteye.com/upload/attachment/0115/6757/ff90d33c-2e12-3a10-a6d9-6c0cea7ca7f6.png[/img]
浏览器的多选项卡之间是共有一个Session的,所以这种情况下一般需要通过以下方法来访问系统:
1)打开不同的浏览器,比如:IE、FF、Chrome
2)打开同一浏览器的多个窗口(不是Ctrl+N打开)
IE: File>New Session
FF: File>New Private Window(Ctrl+Shift+P)
Chrome: Menu>New incognito Window(Ctrl+Shift+N)
这两种方法只能针对开发测试的,对用户来说就有些牵强了。
如何让系统支持多用户在多选项卡间同时登陆?首先最基本的需要采用ACL权限控制来保证用户的权限不会越级,比如上边这个场景不至于普通User执行了Admin的操作。
其次需要让多个选项卡之间只允许一个用户登录。
1)过滤请求,如果访问的是登录页,查看Session中是否已有用户信息,直接跳向指定页。
HttpSession session = request.getSession();
User user = (User) session.getAttribute("LOGIN_USER_INFO");
if (user == null) {
// Session Timeout
response.sendRedirect("LOGIN_URL");
return false;
} else {
// Multiple or Repeated Login
if ("LOGIN_URL".equals(request.getRequestURI())) {
response.sendRedirect("HOME_URL");
return false;
}
}
2)成功登陆后新建一个会话,删除老的会话,可防御会话劫持Session Fixation / Hijacking。
HttpSession oldSession = request.getSession(false);
if (oldSession != null && !oldSession.isNew()) {
// store the old session
Enumeration attrNames = oldSession.getAttributeNames();
Properties props = new Properties();
if (attrNames != null) {
while (attrNames.hasMoreElements()) {
String key = (String) attrNames.nextElement();
props.put(key, oldSession.getAttribute(key));
}
}
// invalidate the old session
oldSession.invalidate();
// generate a new session
HttpSession newSession = request.getSession(true);
// copy the data of the old session into the new session
attrNames = props.keys();
while (attrNames.hasMoreElements()) {
String key = (String) attrNames.nextElement();
newSession.setAttribute(key, props.get(key));
}
}
另外两个问题:
1)限制同一个用户在同一时间只能登录一次
这里说的不是SSO单点登录,而是防止一个账户多处登录
在服务器端存储一个User的会话Map<User, Session>(或存入DB)
创建一个HttpSessionListener来监听会话,如果该User的会话已经存在用新的会话替换它。
2)同一服务器多应用的会话管理
Tomcat使用JSESSIONID作为默认的Cookie键值来识别Session,也可以自定义该键值:
<Host name="localhost" appBase="webapps"...>
<Context path="/appA" sessionCookieName="yourCookieName"/>
</Host>