结合 PrettyFaces 和 PicketLink

Posted

技术标签:

【中文标题】结合 PrettyFaces 和 PicketLink【英文标题】:Combining PrettyFaces and PicketLink 【发布时间】:2016-11-28 14:55:13 【问题描述】:

当使用 PrettyFaces/Rewrite 重写 JSF 应用程序中的 URL 并使用 PicketLink 保护它时,PicketLink 似乎没有使用重写规则。

例如,如果我用这样的方式配置 PicketLink:

builder
    .http()
        .allPaths()
            .authenticateWith()
                .form()
                    .loginPage("/common/login.xhtml")

并且有这样的重写规则:

<url-mapping id="login">
    <pattern value="/login" />
    <view-id value="/common/login.xhtml" />
</url-mapping>

用户将被重定向到/common/login.xhtml,而不是/login

我知道我可以在 PicketLink 中使用 /login 作为 loginPage,但是直到现在,我已经能够以一种完全透明的方式为我的应用程序使用 PrettyFaces/Rewrite(我可以删除它,一切仍然可以正常工作。 .. 但 URL 很丑)。

我注意到来自 PicketLink 的 SecurityFilter 似乎在来自 PrettyFaces/Rewrite 的 RewriteFilter 之前:

    at org.ocpsoft.rewrite.servlet.impl.HttpRewriteResultHandler.handleResult(HttpRewriteResultHandler.java:41)
    at org.ocpsoft.rewrite.servlet.RewriteFilter.rewrite(RewriteFilter.java:268)
    at org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(RewriteFilter.java:188)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.picketlink.http.internal.SecurityFilter.processRequest(SecurityFilter.java:346)
    at org.picketlink.http.internal.SecurityFilter.performOutboundProcessing(SecurityFilter.java:237)
    at org.picketlink.http.internal.SecurityFilter.doFilter(SecurityFilter.java:196)

因此,如果 PrettyFaces 以某种方式包装 HttpServletResponse 以覆盖 encodeRedirectUrl(),则 SecurityFilter 将不会像以前那样看到这个包装的响应。

有没有办法让RewriteFilter 出现在SecurityFilter 之前?

我没有在我的部署描述符中声明这些过滤器,它们是通过 web-fragment.xml 用于 PrettyFaces 和通过 @WebListener 用于 PicketLink 自动注册的。

【问题讨论】:

【参考方案1】:

您可以尝试将absolute-ordering 元素添加到您的 web.xml 以控制排序。比如:

<web-app> 
    ... 
    <absolute-ordering> 
        <name>com_ocpsoft_rewrite</name> 
        <others/> 
    <absolute-ordering> 
    ...
</web-app>

【讨论】:

正确!使用绝对排序来解决这个问题。 这不起作用:SecurityFilter 仍然在 RewriteFilter 之前。我认为这来自两个框架如何注册它们各自的过滤器:PicketLink 从其PicketLinkServletContextListener 注册它的过滤器,而 Rewrite 在web-fragment.xml 中注册它的过滤器。我认为首先处理所有ServletContextListeners(因此PicketLink 注册其过滤器),然后添加来自DD 的所有其他过滤器(重写)。所以排序在这里没有影响。我已经设置了两个过滤器的断点,SecurityFilterRewriteFilter 之前被初始化/链接。 一个可能的解决方案是 Rewrite 从它自己的RewriteServletContextListener 注册它的过滤器。 我设法通过在web.xml 或自定义web-fragment.xml 中声明它们以正确的顺序获得过滤器,绝对排序为#1。不幸的是,这并不能解决我的问题:当 PicketLink 重定向到登录页面时,url 没有被重写,所以这可能是 PicketLink 中的问题(不使用encodeRedirectURL()?)。 问题可能来自org.picketlink.http.internal.authentication.schemes.FormAuthenticationScheme.forwardToLoginPage(),它在重定向之前没有对URL进行编码。

以上是关于结合 PrettyFaces 和 PicketLink的主要内容,如果未能解决你的问题,请参考以下文章

Primefaces FileUpload 与 PrettyFaces 和 JSF 2.2.3

PrettyFaces 和 h:link 结果标签不会重定向到干净的 URL

JSF2 和 PrettyFaces...如何获取原始 URL 或查询字符串?

使用 PrettyFaces 获取原始请求 URI

JSF2 <h:selectOneMenu 和 <f:ajax 侦听器在 PrettyFaces 过滤器导航之后未调用

如何在 PrettyFaces 的帮助下将长的 Liferay URL 映射到友好的 URL?