http - 如何跨 HTTP 和 HTTPS 请求重用 SessionScope 的 JSF Beans?

标签 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 上点击“使 session 无效”。
  2. 重新加载 W1。
  3. 重新加载 W2。

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 上单击“使 session 无效”。
  2. 重新加载 W2。
  3. 重新加载 W1。

输出是。

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

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

此示例使用带有 JSF 2.2 (Mojarra) 的 Glassfish 4.1

最佳答案

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

在 HTTPS 请求期间创建的 Cookie 不可用于同一域/路径上的 HTTP 请求。否则这将是一个安全漏洞,会破坏 HTTPS 的完整性和意义。只有反过来才有可能。

只需从 HTTP 永久重定向到 HTTPS,即可在您的 Web 应用程序上禁用 HTTP。

关于http - 如何跨 HTTP 和 HTTPS 请求重用 SessionScope 的 JSF Beans?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31516877/

相关文章:

node.js - Node : listen EACCES: permission denied 0. 0.0.0:80

SSL 证书在 cpanel 中不起作用

sql-server - 如何通过REST查询SQL Server获取XML

java - 通过 HTTP 使用 Commons-VFS

jsf - 通过 JSF 将 PDF 发送到浏览器

java - 如何在 JSF2.0 中使用 RichFaces4.0? RichFaces4.0如何配置View Handler?

jsf-2 - 如何将 List<Integer> 值绑定(bind)到 JSF 中的 selectManyListbox

java - 在 Docker Toolbox 中运行 Java 应用程序时出现 SunCertPathBuilderException

java - 在 Java 中发送对象列表作为响应

java - 使用 HttpURLConnection 的 Android 应用程序在 connect() 处崩溃