Jsf 如何正确注销其他用户

Jsf 如何正确注销其他用户,jsf,jakarta-ee,jsf-2.2,logout,httpsession,Jsf,Jakarta Ee,Jsf 2.2,Logout,Httpsession,在我的web应用程序中,我试图实现管理员的功能 能够注销其他当前登录的用户 到目前为止我所做的: 我创建了一个POJO来存储重要的用户信息,包括对用户HTTP会话的引用 此POJO正在实现HttpSessionBindingListener 在登录过程中,我将此POJO的一个实例放入SessionMap。通过valueBound方法,我将其放入一个静态映射中,该映射存储所有此类登录用户信息(在未绑定事件中,我将再次删除它) 在单独的管理部分,我现在可以访问特定用户的HttpSession,并使

在我的web应用程序中,我试图实现管理员的功能 能够注销其他当前登录的用户

到目前为止我所做的:

  • 我创建了一个POJO来存储重要的用户信息,包括对用户HTTP会话的引用
  • 此POJO正在实现
    HttpSessionBindingListener
  • 在登录过程中,我将此POJO的一个实例放入SessionMap。通过
    valueBound
    方法,我将其放入一个静态映射中,该映射存储所有此类登录用户信息(在未绑定事件中,我将再次删除它)
  • 在单独的管理部分,我现在可以访问特定用户的
    HttpSession
    ,并使其无效
  • 已注销的用户通过websocket获得已注销的通知
使
HttpSession
无效工作正常,并调用所提到的
unbound
方法。但是,问题是,如果以这种方式注销的用户仍然能够执行AJAX请求,则会创建一个新的hte ViewScoped Bean实例并将其分配给客户端,并且该请求与此新实例相反

我所期望的(或我想要实现的)是,像ViewExpiredException这样的东西会被抛出,并将用户重定向到登录页面。
还是我缺少了我概念中的一个重要部分

web.xml
中设置适当的安全约束就足够了,还是仅仅隐藏了概念上的问题

(如果这很重要,那么Bean不是JSFbean,而是CDI视图范围的Bean。)

应用程序正在Glassfish 4.1、Mojarra 2.2.12上运行


SessionBindingListener:

@RequiredArgsConstructor
@EqualsAndHashCode(of = {"user"})
public class UserSessionInfo implements HttpSessionBindingListener {

    @Getter private static final Map<UserSessionInfo, UserSessionInfo> sessions 
         = new HashMap<>(10);

    @Getter private final String user;
    @Getter private HttpSession session;

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

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

}
注销其他用户的管理方法:

public void logoff(UserSessionInfo usr) {
    EventBus eventBus = EventBusFactory.getDefault().eventBus();        
    eventBus.publish(CHANNEL, new DialogMessage(/*...*/));        
    usr.getSession().invalidate();           
}

如果用户的会话真的无效,那么所有请求都应该失败,不管是否是ajax

在我的一个应用程序中,我有:

  • 安全限制,通过web.xml中的角色
  • 使用HttpSessionListener和筛选器进行会话跟踪(筛选器是我在登录时检测tomcat创建的新会话的方式,以避免会话固定)
  • 使用session.invalidate“杀死”另一个会话的可能性
如果会话是“在您的后台”重新创建的,那一定是因为您有一个不受限制的访问区域。需要对您的所有会话进行身份验证,规则如下:

<security-constraint>
    <display-name>Authenticated users</display-name>
    <web-resource-collection>
        <web-resource-name>Authenticated users</web-resource-name>
        <url-pattern>/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>*</role-name>
    </auth-constraint>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

认证用户
认证用户
/*
收到
邮递
*
保密的
在web.xml中,应该可以

<security-constraint>
    <display-name>Authenticated users</display-name>
    <web-resource-collection>
        <web-resource-name>Authenticated users</web-resource-name>
        <url-pattern>/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>*</role-name>
    </auth-constraint>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>