如何跨HTTP和HTTPS请求重用SessionScope的JSF Bean?

时间:2015-07-20 12:44:36

标签: http jsf-2 https

考虑这个index.xhtml页面。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html">
    <f:view locale="en" encoding="UTF-8">
        <h:head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        </h:head>

        <h:body class="ui-grid" id="body">
            <h:form>
                <h:commandButton value="Invalidate Session" action="#{loggedInUser.invalidateSession}"/>
            </h:form>
        </h:body>
    </f:view>
</html>

这个SessionScoped bean。

import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

@Named
@SessionScoped
public class LoggedInUser implements Serializable {

    String user;

    @PostConstruct
    public void init() {
        String remoteUser = this.user = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
        String sessionId = FacesContext.getCurrentInstance().getExternalContext().getSessionId(false);
        System.out.println("Initializing. With SESSION ID " + sessionId);
        System.out.println("Initializing. With remote user " + remoteUser);
    }

    public void invalidateSession() throws ServletException{
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        request.logout();
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }
}

我在两个浏览器窗口中访问该页面。 一个窗口(W1)具有URL https://localhost:8181/pfdialogdemo/index.xhtml 另一个窗口(W2)具有URL http://localhost:8080/pfdialogdemo/index.xhtml

这些是我的步骤。

  1. 在W1上点击“无效会话”。
  2. 重新装载W1。
  3. 重新载入W2。
  4. LoggedInUser.init()生成的输出;是

    Information:   Initializing. With SESSION ID b6d2858cc441c52540f54ee4cb0c  
    Information:   Initializing. With remote user null 
    Information:   Initializing. With SESSION ID b6d60472f8d5cca5b6feb5ff32d5 
    Information:   Initializing. With remote user null
    

    如果我这样做。

    1. 在W2上点击“无效会话”。
    2. 重新载入W2。
    3. 重新装载W1。
    4. 输出是。

      Information:   Initializing. With SESSION ID b6de615078648aa44566af533a9f
      Information:   Initializing. With remote user null
      

      为什么在第一个示例中第二次创建了SessionScoped bean?如何确保SessionScoped bean没有创建两次?为什么在第二个例子中只创建一次?

      此示例使用Glassfish 4.1和JSF 2.2(Mojarra)

1 个答案:

答案 0 :(得分:0)

预期行为符合HTTP state (cookie) specification(即超出JSF的控制范围)。

在HTTPS请求期间创建的Cookie不可用于同一域/路径上的HTTP请求。否则,这将是一种破坏HTTPS完整性和感觉的安全漏洞。这是唯一可能的反过来。

只需通过从HTTP永久重定向到HTTPS来禁用Web应用程序上的HTTP。