JSF身份验证:无法拦截错误消息 [英] JSF Authentication: cannot intercept error messages

查看:172
本文介绍了JSF身份验证:无法拦截错误消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经开发了一个简单的登录表单,可用于我的JSF + PrimeFaces页面:

I have developed a simple login form to be used in my JSF + PrimeFaces page:

<form action="j_security_check" method="post"> 
    <p:dialog modal="true" header="Login" widgetVar="loginDlg">
        <h:panelGrid columns="3" cellpadding="5">  
            <h:outputLabel for="j_username">Username:</h:outputLabel> 
            <h:inputText id="j_username" required="true" /> 
            <h:message for="j_username" /> 
            <h:outputLabel for="j_password">Password:</h:outputLabel> 
            <h:inputSecret id="j_password" required="true" /> 
            <h:message for="j_password" /> 
            <br /> 
            <h:commandButton value="Login" /> 
        </h:panelGrid>
    </p:dialog>                
</form> 

尝试使用空密码,但是h:message组件未捕获缺少的密码(必需).我还切换到了p:commandButton,认为问题可能出在按钮的Ajax行为上,但是未渲染页面,因为PrimeFaces抱怨CommandButton不在表单元素中.容器抛出的异常是:

Tried with an empty password, but the missing password (that is required) is not caught by h:message component. I have also switched to a p:commandButton thinking that the problem could have been in the Ajax behaviour of the button, but the page is not rendered because PrimeFaces complains about the CommandButton not being inside a form element. The exception thrown by the container is:

com.sun.enterprise.security.auth.login.common.LoginException: Login failed: Access denied on empty password for user pippo

总而言之,我有两个问题:

To summarize, I have 2 questions:

  1. 为什么在提交表单之前丢失的密码不会产生消息?
  2. 如何捕获LoginException并在对话框中显示错误消息?

推荐答案

j_security_check请求由Web容器而不是JSF处理.这说明required="true"无法正常工作.仅当您在与命令按钮关联的操作方法中使用JSF <h:form>和通过HttpServletRequest#login()进行程序化登录时有效.

The j_security_check request is handled by the web container, not by JSF. That explains that the required="true" won't work. It works only when you use JSF <h:form> and programmatic login by HttpServletRequest#login() in the action method associated with the command button.

最好的办法是配置web.xml中的<form-error-page>指向与<form-login-page>相同的URL.然后,您可以检查请求是否已由j_security_check本身转发,这意味着发生登录错误.

Best what you can do is to confiure a <form-error-page> in web.xml pointing to the very same URL as the <form-login-page>. You could then check if the request has been forwarded by j_security_check itself, which would mean that a login error has occurred.

<h:panelGroup rendered="#{requestScope['javax.servlet.forward.servlet_path'] == '/j_security_check'}">
    <h:outputText value="Unknown login, please try again" styleClass="error" />
</h:panelGroup>

使用它代替<h:message>.

关于<p:commandButton>为什么抱怨没有表格的原因仅仅是因为您没有使用<h:form>.

As to why <p:commandButton> complains that there's no form is simply because you didn't use <h:form>.

无关与具体问题无关,最好将<form>(或<h:form>,无论何时您决定切换到程序化登录名)放在<p:dialog>的正文中,而不是放在外部. JS可以将<p:dialog>重定位到正文的末尾,这将导致它不再具有某种形式.

Unrelated to the concrete problem, that <form> (or <h:form> whenever you would decide to switch to programmatic login) can better be placed in the body of <p:dialog>, not outside. The <p:dialog> can by JS be relocated to end of body which would cause it not to be in a form anymore.

这篇关于JSF身份验证:无法拦截错误消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆