在 JSF 登录期间何时创建会话?

Posted

技术标签:

【中文标题】在 JSF 登录期间何时创建会话?【英文标题】:When is session created during JSF login? 【发布时间】:2013-01-27 20:18:09 【问题描述】:

在 JSF 中,似乎会话是在成功登录之前创建的。即简单地请求登录页面会导致创建一个新会话。

为收到的每个请求而不是每个成功登录的用户创建会话似乎非常浪费(并且容易受到 DDoS 攻击)。

下面的代码非常通用,但显示了我所指的那种简单场景。

index.xhtml:

<html>
    <body>
        <h:form id="login">
            <h:outputLabel for="username">Username</h:outputLabel>
            <p:inputText id="username" name="username" value="#userController.username"/>
            <h:outputLabel for="password">Password</h:outputLabel>
            <p:password id="password" name="password" value="#userController.password"/>

            <p:commandButton id="loginButton" value="login" action="#loginController.login"/>
        </h:form>
    </body>
</html>

LoginController.java

@ViewScoped
public class LoginController implements Serializable 

    String username;
    String password;

    public void login()
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        if (request.getSession(false) == null)
            System.out.println("No session.");
         else 
            System.out.println("Session already exists.");
        

        try 
            request.login(username, password);
         catch (ServletException e) 
            FacesContext.getCurrentInstance.addMessage(null, new FacesMessage("Login failure", e.getMessage()));
        
    

    // username and password getters/setters


编辑:杂乱无章的代码示例已修复

【问题讨论】:

【参考方案1】:

首先,你的测试方法是完全错误的。

if (request.getSession() == null)
    System.out.println("No session.");
 else 
    System.out.println("Session already exists.");

请仔细阅读无参数getSession() 方法的javadoc。你会发现它从不返回null

回到具体问题,默认情况下 JSF 确实会自动创建会话,因为 JSF 视图状态必须存储在那里。如果将 JSF 状态保存方法设置为client 而不是server,则不会存储在 session 中,因此不需要创建 session。

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

在即将到来的 JSF 2.2 中,您也可以将 bean 放入请求范围并使用 &lt;f:view transient="true"&gt; 来完全无状态。这适用于自 Mojarra 2.1.19 起才可用的当前 JSF 2.1 版本。另见例如this blog 来自 Mojarra 开发人员之一。

【讨论】:

忏悔 - 示例代码大量改编自我们的生产代码。我最初使用的是 getSession(false)。但除此之外,感谢您确认我的想法。尽管四处寻找(书籍、博客、Oracle 文档),但我没有找到 JSF 自动创建会话的明确确认。 顺便说一句,这确实可以通过向服务器发出新的登录请求(尽管没有可用的登录凭据)来更容易地关闭服务器吗? 取决于服务器硬件和配置。例如。连接/请求池、会话超时、可用内存、网络带宽等。测量就是知道。

以上是关于在 JSF 登录期间何时创建会话?的主要内容,如果未能解决你的问题,请参考以下文章

JSF HTTP 会话登录

JSF 登录过滤器,会话为空

新的 Spring Security 登录会话启动时是不是启动了新的 JSF 会话?

会话范围和 jsf 重定向

JSF 2 + Spring 3 + Shiro - 会话超时不重定向到登录页面

会话固定 - 登录后删除会话并创建新会话 - 但用户不再登录