如何使用相同的凭据记录两次用户会话时使其无效

pak*_*ore 19 java session jsf richfaces facelets

我正在使用带有Richfaces和Facelets的JSF 1.2.

我有一个应用程序,有许多会话范围的bean和一些应用程序bean.

用户使用Firefox登录.创建一个ID ="A"的会话; 然后他打开Chrome并使用相同的凭据再次登录.创建ID ="B"的会话.

当创建会话"B"时,我希望能够销毁会话"A".怎么做?

也.当Firefox中的用户做任何事情时,我希望能够显示一个弹出窗口或某种通知,说"你已经登出,因为你已经从其他地方登录".

我有一个sessionListener,可以跟踪创建和销毁的会话.问题是,我可以将HTTPSession对象保存在应用程序范围的bean中,并在检测到用户已登录两次时将其销毁.但有些东西告诉我这是错误的,不会奏效.

JSF是否跟踪服务器端的某些会话?如何通过标识符访问它们?如果没有,如何在用户登录两次时首次登录?

Bal*_*usC 20

在DB-独立的做法是让Userstatic Map<User, HttpSession>变量和执行HttpSessionBindingListener(和Object#equals()Object#hashCode()).这样,你的webapp仍会在意外崩溃后仍然运行,这可能导致数据库值不会更新(你当然可以创建一个ServletContextListener在webapp启动时重置数据库,但这只是越来越多的工作).

这是User应该是这样的:

public class User implements HttpSessionBindingListener {

    // All logins.
    private static Map<User, HttpSession> logins = new ConcurrentHashMap<>();

    // Normal properties.
    private Long id;
    private String username;
    // Etc.. Of course with public getters+setters.

    @Override
    public boolean equals(Object other) {
        return (other instanceof User) && (id != null) ? id.equals(((User) other).id) : (other == this);
    }

    @Override
    public int hashCode() {
        return (id != null) ? (this.getClass().hashCode() + id.hashCode()) : super.hashCode();
    }

    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        HttpSession session = logins.remove(this);
        if (session != null) {
            session.invalidate();
        }
        logins.put(this, event.getSession());
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        logins.remove(this);
    }

}
Run Code Online (Sandbox Code Playgroud)

当您登录时User如下:

User user = userDAO.find(username, password);
if (user != null) {
    sessionMap.put("user", user);
} else {
    // Show error.
}
Run Code Online (Sandbox Code Playgroud)

然后它将调用valueBound()将从logins地图中删除任何先前登录的用户并使会话无效.

当您注销时User如下:

sessionMap.remove("user");
Run Code Online (Sandbox Code Playgroud)

或者当会话超时时,valueUnbound()将调用将logins地图中的用户删除.