Аутентификация JSF: не может перехватывать сообщения об ошибках

Я разработал простую форму входа для использования на моей странице JSF + PrimeFaces:

<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 не находится внутри элемента формы. Исключение, выдаваемое контейнером:

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

Подводя итог, у меня 2 вопроса:

  1. Почему отсутствующий пароль не выводит сообщение перед отправкой формы?
  2. Как я могу поймать LoginException и отобразить сообщение об ошибке в диалоговом окне?

person perissf    schedule 28.04.2012    source источник
comment
Попробуйте поставить туда <h:messages />, это должно перехватить все сообщения об ошибках на всей странице   -  person Petr Mensik    schedule 29.04.2012


Ответы (1)


Запрос j_security_check обрабатывается веб-контейнером, а не JSF. Это объясняет, что required="true" не работает. Это работает, только если вы используете JSF <h:form> и программный вход в систему с помощью HttpServletRequest#login() в методе действия, связанном с командной кнопкой.

Лучшее, что вы можете сделать, это настроить <form-error-page> в web.xml, указывающем на тот же URL, что и <form-login-page>. Затем вы можете проверить, был ли запрос перенаправлен самим j_security_check, что означало бы, что произошла ошибка входа.

<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>.


Не связанный с конкретной проблемой, <form> (или <h:form> всякий раз, когда вы решите переключиться на программный вход) лучше разместить в теле <p:dialog>, а не снаружи. <p:dialog> можно с помощью JS переместить в конец тела, что приведет к тому, что он больше не будет в форме.

person BalusC    schedule 29.04.2012
comment
Спасибо BalusC. В этом случае я буду использовать чистую форму входа JSF и сеансовый компонент для аутентификации, как описано здесь: stackoverflow.com/questions/2206911/ - person perissf; 29.04.2012