【问题标题】:JSF redirects from HTTPS to HTTPJSF 从 HTTPS 重定向到 HTTP
【发布时间】:2014-01-03 13:48:35
【问题描述】:

我在测试服务器上的应用程序仅通过 https 执行。当我在不重定向的情况下导航时,它可以完美运行:

例子:

<p:menuitem value="#{msg.customerScreen}" url="/restrict/customer.xhtml" />
<p:menuitem value="#{msg.productScreen}" url="/restrict/product.xhtml" />

但是当我需要重定向到另一个页面时,它会重定向到 http 而不是 https。通过 http 使用时,它可以完美运行:

<p:commandLink ajax="false" action="/commerce/store.xhtml?faces-redirect=true">
    <h:graphicImage library="images/BTN" name="btn_to_shop.gif"/>
</p:commandLink>

作为一种解决方法,我尝试重建 URL:

<p:commandLink ajax="false" action="#{authorizerBean.getCompleteURL('/commerce/store.xhtml?faces-redirect=true')}">
    <h:graphicImage library="images/BTN" name="btn_to_shop.gif"/>
</p:commandLink>

public String getCompleteURL(String page) {
    try {
        FacesContext ctxt = FacesContext.getCurrentInstance();
        ExternalContext ext = ctxt.getExternalContext();

        URI uri = new URI(ext.getRequestScheme(), null, ext.getRequestServerName(), ext.getRequestServerPort(), ext.getRequestContextPath(), null, null);
        return uri.toASCIIString() + page;
    } catch (URISyntaxException e) {
        throw new FacesException(e);
    }
}

方法 getCompleteURL 被调用并返回正确的 URL,但 JSF 没有重定向到新的 URL。

JBoss 正在接收 HTTP 连接。管理 HTTPS 的是 Apache,它重定向到 JBoss:

<VirtualHost *:443>

    ...

    ProxyPass / http://server:8080/
    ProxyPassReverse / http://server:8080/
</VirtualHost>

我更愿意在不使用 getCompleteURL 的情况下解决此问题,但如果不可能,请帮助我使用其他方法。

【问题讨论】:

标签: jsf https


【解决方案1】:

我找到了解决此问题的方法。我认为这是因为 Apache 接收到 https 连接并通过 http 转发给 JBoss。然后当我重定向到另一个页面时,JSF 不知道它应该通过 https 进行。

使用 ConfigurableNavigationHandler,我可以在重定向时拦截并挂载正确的 URL。

public class NavigationHandler extends ConfigurableNavigationHandler {

    private ConfigurableNavigationHandler concreteHandler;

    public NavigationHandler(ConfigurableNavigationHandler concreteHandler) {
        this.concreteHandler = concreteHandler;
    }

    @Override
    public void handleNavigation(FacesContext context, String fromAction, String outcome) {
        if (outcome != null && outcome.contains("faces-redirect=true")) {
            try {
                outcome = "https://server.com/project" + outcome;
                context.getExternalContext().redirect( outcome );
            } catch (IOException e) {
                throw new FacesException(e);
            }
        } else {
            concreteHandler.handleNavigation(context, fromAction, outcome);   
        }
    }
}

在 faces-config.xml 中:

<application>
    <navigation-handler>com.example.NavigationHandler</navigation-handler>
</application> 

【讨论】:

    【解决方案2】:

    另一种解决方法是设置

    RequestHeader set X-Forwarded-Proto https
    RequestHeader set X-Forwarded-Port 443
    

    在 Apache 的虚拟主机上。

    JSF 将知道重定向应该是 HTTPS 连接,并且不需要更改代码。

    我已经将它与 Apache 和 Wildfly 一起使用。

    【讨论】:

      猜你喜欢
      • 2019-09-10
      • 2017-10-06
      • 1970-01-01
      • 2017-11-04
      • 2016-01-17
      • 2011-09-28
      • 2017-07-18
      • 2018-04-09
      相关资源
      最近更新 更多