我正在使用Java EE 6(JSF CDI EJB)的Web应用程序,它不应该允许并发登录(相同的用户和传递)。
我喜欢的是:
如果用户登录两次,则第一个会话需要失效,旧会话数据(包括所有带有SessionScope的CDI Bean或其他范围,如来自Apache CODI的WindowScope)将被转移到新会话。
这就像是一个想要的会话劫持方法: - )
答案 0 :(得分:0)
Java EE 6中没有固有的机制。
由于我无法想象你想将一个持续的用例(例如一个开放的结账过程)从一个会话转移到另一个会话,我建议你只需跟踪用户的GUI状态
RESTful URL听起来像是一种理想的方法。保留最后一个用户URL /用户操作(例如www.myapp.com/orders/new/12
)并在新登录时重新打开它。
如果您不想在数据库中保留此内容,则应用程序范围的地图userid / url可能是KISS方式。
答案 1 :(得分:0)
您可以为用户使用无状态bean,因此每次尝试登录/重新登录时,当前会话都会失效(在登录过程开始时)
考虑这种方法:
try {
session = request.getSession(); //the request is passed by another page or action
if(session.getAttribute("user") != null) {
//your code to forward or handle the existing user (re-log in/ do nothing etc.)
}
答案 2 :(得分:0)
我借助过滤器解决了这个问题
公共类SessionReplicationFilter实现Filter {
@Inject
SessionReplicationManager manager;
public SessionReplicationFilter() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//Process chain first
if (chain != null) {
chain.doFilter(request, response);
}
//check http request
if (request instanceof HttpServletRequest) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
// Retrieve the session and the principal (authenticated user)
// The principal name is actually the username
HttpSession session = httpRequest.getSession();
Principal principal = httpRequest.getUserPrincipal();
if (principal != null && principal.getName() != null && session != null) {
manager.checkExistingSession(principal.getName(), session))
}
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
经理看起来跟着
@ApplicationScoped 公共类SessionReplicationManager {
private Map<String, HttpSession> map = new ConcurrentHashMap<String, HttpSession>();
public boolean checkExistingSession(String user, HttpSession session) {
if (map.keySet().contains(user)) {
if (!session.getId().equals(map.get(user).getId())) {
System.out.println("User already logged in ");
HttpSession oldSession = map.get(user);
// copies all attributes from the old session to the new session (replicate the session)
Enumeration<String> enumeration = oldSession.getAttributeNames();
while (enumeration.hasMoreElements()) {
String name = enumeration.nextElement();
System.out.println("Chaning attribut " + name);
session.setAttribute(name, oldSession.getAttribute(name));
}
// invalidates the old user session (this keeps one session per user)
oldSession.invalidate();
map.put(user, session);
return true;
}
} else {
System.out.println("Putting "+user+" into session cache");
map.put(user, session);
return false;
}
return false;
}
}
与CoDI ViewScoped带注释的Beans
配合得很好如果第一个用户失效,则每个(AJAX)请求都会导致会话过期异常,即使使用恢复会话按钮也可以轻松处理
只有viewcoped bean的一个小问题是,他们获得了一个新的视图ID。通过将它们更改回原点,一切正常。
我需要添加的内容:
在此评论中遗漏:
此致