Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jsf 使用CustomFormAuth和o:form登录时未正确转发_Jsf_Jakarta Ee_Omnifaces_Java Ee 8 - Fatal编程技术网

Jsf 使用CustomFormAuth和o:form登录时未正确转发

Jsf 使用CustomFormAuth和o:form登录时未正确转发,jsf,jakarta-ee,omnifaces,java-ee-8,Jsf,Jakarta Ee,Omnifaces,Java Ee 8,我试图在我的web项目上实现雅加达安全性,为此我遵循了Bauke Scholtz和Arjan Tijms令人惊叹的“JavaEE8中JSF的权威指南”,但似乎我遇到了麻烦 当我在地址栏中键入受限url时,转发会正常进行,我看到登录页面,但在提交表单后,页面不会重定向,登录页面似乎会重新加载(字段为空,但地址栏中的url仍然是受限页面中的url) 在日志的帮助下,我知道AuthenticationStatus返回为SUCCESS,但即使如此,如果我手动将地址栏更改为另一个受限url,它也会被转发到

我试图在我的web项目上实现雅加达安全性,为此我遵循了Bauke Scholtz和Arjan Tijms令人惊叹的“JavaEE8中JSF的权威指南”,但似乎我遇到了麻烦

当我在地址栏中键入受限url时,转发会正常进行,我看到登录页面,但在提交表单后,页面不会重定向,登录页面似乎会重新加载(字段为空,但地址栏中的url仍然是受限页面中的url)

在日志的帮助下,我知道
AuthenticationStatus
返回为
SUCCESS
,但即使如此,如果我手动将地址栏更改为另一个受限url,它也会被转发到登录页面

如果我在地址栏中键入/登录并提交,验证和重定向将正常进行

如果我使
useForwardToLogin=false
正常工作,但是
getForwardURL
总是返回null,并且我无法将用户重定向到他们想要访问的页面

谢谢你的帮助

ApplicationConfig.java

@CustomFormAuthenticationMechanismDefinition(
        loginToContinue = @LoginToContinue(
                loginPage = "/login",
                errorPage = ""
        )
)
@FacesConfig
@ApplicationScoped
public class ApplicationConfig {

}
login.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:c="http://java.sun.com/jsp/jstl/core"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
                xmlns:p="http://primefaces.org/ui"
                xmlns:o="http://omnifaces.org/ui"
                template="/WEB-INF/templates/login.xhtml">
    <ui:define name="content">
        <c:choose>
            <c:when test="#{not empty request.userPrincipal}">
                <div>Already logged</div>
            </c:when>
            <c:otherwise>
                <o:form>
                    <p:inputText id="login" value="#{loginBacking.userName}" required="true"/>
                    <p:password id="pwd" value="#{loginBacking.password}" required="true"/>
                    <p:inputNumber id="otp" value="#{loginBacking.otp}" />
                    
                    <o:messages id="messages" var="message">
                        <div class="#{fn:toLowerCase(message.severity)}">#{message.summary}</div>
                    </o:messages>

                    <p:commandButton value="Submit" action="#{loginBacking.login}" update="@form"/>
                </o:form>
            </c:otherwise>
        </c:choose>
    </ui:define>
</ui:composition>

FIY,如你所见,我正在使用Omnifaces、Primefaces和Lombok。

根据Kukeltje的建议,我制作了一个你可以在这里找到的最简单的工作示例。 它是由Bauke Scholtz和Arjan Tijms=>撰写的《JavaEE8中JSF的最终指南》一书中repo安全部分的一个修改分支

它工作得非常好,所以我决定添加omnifaces和primefaces,并意识到:

  • 正如这里所说的,如果您使用的是primefaces'
    p:commandButton
    ,那么应该向其添加
    ajax=false
    属性
  • 如果您使用的是omnifaces'
    o:form
    ,则应向其添加
    useRequestURI=“false”
    属性。这是有意义的,因为my fork使用forward来访问登录页面,所以URL和URI是您想要访问的任何页面的URL和URI,并且当o:form上的
    useRequestURI
    设置为
    true
    (默认值)时,它会提交表单,因此不会提交到登录页面

  • 非常感谢Kukeltje为我指明了正确的方向。

    我有似曾相识的经历…@Kukeltje我也是:。不管怎样,我找到了一个解决办法。我想我没有找到合适的工作来寻找类似的问题,对不起@Kukeltje我看到了这篇文章,但是在commandButton中添加ajax=false并没有改变任何事情@Marcos,我也应该实现OTP,所以我不能使用
    @FormAuthenticationMechanismDefinition
    SylvainAutran:我也找不到最近类似的帖子。。。奇怪的因此,感谢@Marcos将其链接。。我们会看看是否能找到原因和解决办法。你能做一个没有模板,没有jstl,没有lombok,没有简单的jsf组件,没有omnifaces等吗?是的,我会尝试这样做。你使用的是什么应用服务器?Payara 5,版本201和2020.2我在Wildfly 20中克隆并执行了你的示例。当执行方法
    Login#continueAuthentication
    时,我被重定向到500.xhtml页面,服务器JSF实现中出现
    NullPointerException
    错误:
    UT005023:异常处理请求到/jakartasecurity/login.xhtml:javax.servlet.ServletException:java.lang.NullPointerException
    javax.faces。api@3.0.0.SP03//javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:725)
    因此,该漏洞似乎在Wildfly中,而不是在我的应用程序或您的示例中。@Marcos:关于您的问题的评论应该在您的问题中!
    @Named
    @RequestScoped
    public class LoginBacking {
        @Inject private SecurityContext securityContext;
    
        @Getter @Setter private String userName;
        @Getter @Setter private String password;
        @Getter @Setter private Integer otp;
    
        public void login() {
            switch (continueAuthentication()) {
                case SEND_CONTINUE:
                    Faces.responseComplete();
                    break;
                case SEND_FAILURE:
                    Messages.addGlobalFatal("Login failed.");
                    break;
                case SUCCESS:
                    redirect();
                    break;
            }
        }
    
        private AuthenticationStatus continueAuthentication() {
            return this.securityContext.authenticate(
                    Faces.getRequest(),
                    Faces.getResponse(),
                    AuthenticationParameters.withParams()
                            .newAuthentication(getForwardURL() == null)
                            .credential(new CustomCredential(userName, password, otp))
            );
        }
    
        private void redirect() {
            CustomUser user = securityContext.getPrincipalsByType(CustomPrincipal.class).stream()
                    .map(CustomPrincipal::getCustomUser)
                    .findAny()
                    .orElse(null);
    
            if (user == null) Messages.addGlobalFatal("Something went wrong.");
    
            String forwardURL = getForwardURL();
            if (forwardURL != null) {
                Faces.redirect(forwardURL);
                return;
            }
            
            Faces.redirect(Faces.getRequestContextPath() + "/restricted/index");
        }
    
        public void logout() throws ServletException {
            Faces.logout();
            Faces.invalidateSession();
            Faces.redirect("login");
        }
    
        public String getForwardURL() {
            String requestURI = Faces.getRequestAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
            String queryString = Faces.getRequestAttribute(RequestDispatcher.FORWARD_QUERY_STRING);
    
            if (requestURI == null) return null;
            return (queryString == null) ? requestURI : (requestURI + "?" + queryString);
        }
    }