业务需求
admin这个账号在A电脑登陆,同时又有一个人在B电脑登陆admin这个账号,那么A电脑上面的admin就不能操作而被强制下线并对A电脑操作的人员进行账号安全提示。同一台电脑不同浏览器可以随意登陆同一个账号,并且不受影响。
实现思路
当用户登陆的时候,小王登录把账号的session和ip存到application里面。小李再次登录账号,先看看这个账号有没有在application里面,如果有把里面的删除掉,把现在的添加进去。当小王进行请求的时候来个过滤器,获取一下现在的session和ip是否与application里面的进行判断,不一样的话证明有人再次登录了,那么就要跳转到登录页面了。就是这个意思了,自行理解吧。
代码
过滤器
<filter>
<filter-name>LoginLimitFilter</filter-name>
<!--Loginfilter类所在位置-->
<filter-class>com.gosoft.wsms.common.filter.Loginfilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginLimitFilter</filter-name>
<!--拦截所有请求了,你可以自行设置-->
<url-pattern>/*</url-pattern>
</filter-mapping>
Loginfilter类
jre自己找吧
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.gosoft.wsms.common.utils.RequestUtil;
import com.gosoft.wsms.common.utils.WebConstants;
public class Loginfilter implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest servletRequest = (HttpServletRequest) request;
HttpServletResponse servletResponse = (HttpServletResponse) response;
HttpSession session = servletRequest.getSession();
ServletContext application = session.getServletContext();
Map<Object, String> userSessionMap = (Map<Object, String>) application.getAttribute("userSessionMap");
String firstUserAcc = (String) session.getAttribute("userAcc");
if (firstUserAcc != null) {//
String currentId = null;
for (Object entry : userSessionMap.keySet()) {
if (firstUserAcc.equals(entry)) {
currentId = userSessionMap.get(firstUserAcc);
}
}
String sessionId =currentId.substring(0,currentId.indexOf(","));
String loginIp =currentId.substring(currentId.indexOf(",")+1);
String lastLoginIp=Loginfilter.getIpAddr(servletRequest);
String currentSessionId=session.getId();
if (null != userSessionMap) {
if(!loginIp.equals(lastLoginIp)){
if (!sessionId.equals(currentSessionId)) {
if (servletRequest.getHeader("x-requested-with") != null
&& servletRequest.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
servletResponse.setContentType("application/json; charset="+ WebConstants.ENCODING);
servletResponse.setHeader("Cache-Control", "no-cache"); // 取消浏览器缓存
servletResponse.setHeader("responseState", "output");// 在响应头设置session状态
PrintWriter out = servletResponse.getWriter();
if (RequestUtil.isMobile(servletRequest)) {
out.print("{\"error_type\":\"error_403\"}");
} else {
out.print("{error_type:'error_403'}");
}
out.flush();
out.close();
} else if (servletRequest.getParameter("requestHeader") != null
&& servletRequest.getParameter("requestHeader").equalsIgnoreCase("XMLHttpRequest")) {
servletResponse.setContentType("application/json; charset="+ WebConstants.ENCODING);
servletResponse.setHeader("Cache-Control", "no-cache"); // 取消浏览器缓存
servletResponse.setHeader("responseState", "output");// 在响应头设置session状态
PrintWriter out = servletResponse.getWriter();
if (RequestUtil.isMobile(servletRequest)) {
out.print("{\"error_type\":\"error_403\"}");
} else {
out.print("{error_type:'error_403'}");
}
out.flush();
out.close();
} else {
if (RequestUtil.isMobile(servletRequest)) {
servletRequest.getRequestDispatcher(
"/error/kick.jsp").forward(servletRequest,
servletResponse);
} else {
session.invalidate();
servletRequest.getRequestDispatcher(
"/error/kick.jsp").forward(servletRequest,
servletResponse);
}
}
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
} else {
//继续下一个过滤器或者继续请求
filterChain.doFilter(servletRequest, servletResponse);
}
}else{
filterChain.doFilter(servletRequest, servletResponse);
}
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
private String split(String currentId, String string) {
return null;
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
//获取ip
public static String getIpAddr(HttpServletRequest request){
String ipAddress = request.getHeader("x-forwarded-for");
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){
//根据网卡取本机配置的IP
InetAddress inet=null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress= inet.getHostAddress();
}
}
return ipAddress;
}
}
登录等时候存储session和ip这里没有完整代码
回去账号
Object userAcc=user.get("USER_ACC");
session.setAttribute("userAcc", userAcc);
String ipAddress = request.getHeader("x-forwarded-for");
if(ipAddress == null || ipAddress.length() == 0 ) {
ipAddress = request.getRemoteAddr();
if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){
//根据网卡取本机配置的IP
InetAddress inet=null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress= inet.getHostAddress();
}
}
Map<Object,String> userSessionMap=null;
ServletContext application=session.getServletContext();
//取出key-value对判断
userSessionMap=(Map)application.getAttribute("userSessionMap");
if(null==userSessionMap){
userSessionMap=new HashMap<Object,String>();
application.setAttribute("userSessionMap", userSessionMap);
}
//取出相同userAcc下sessionUserAcc判断是否登陆过
String sessionUserAcc=userSessionMap.get(userAcc);
String sessionIp=session.getId()+","+ipAddress;
if(sessionUserAcc==null){
userSessionMap.put(userAcc, sessionIp);
}else{
userSessionMap.remove(sessionUserAcc);
userSessionMap.put(userAcc,sessionIp);
}