Reputation: 4754
I use a facelets login form for Spring Security:
<h:messages globalOnly="true" layout="table" />
<h:form id="formLogin" prependId="false">
<h:outputLabel for="j_username" value="Usuario:" />
<h:inputText id="j_username" value="#{autenticacionController.administrador.login}" />
<h:outputLabel for="j_password" value="Contraseña:" />
<h:inputSecret id="j_password" value="#{autenticacionController.administrador.password}" />
<h:commandButton value="Entrar" action="#{autenticacionController.loginAction}" />
<h:commandButton value="Cancelar" immediate="true" action="#{autenticacionController.cancelarAction}" />
</h:form>`
The loginAction method forwards the request with this:
FacesContext.getCurrentInstance().getExternalContext().dispatch("/j_spring_security_check")
It works fine, but how can I show a facesmessage in my h:messages tag if the BadCredentials exception is thrown by Spring Security?
I know it can be done with a phase listener, but I don't like that way (dealing with exceptions in listeners).
I'm trying another way, configuring Spring Security like this:
authentication-failure-url="/faces/paginas/autenticacion/login.xhtml?error=1
And then in the login page, catch the GET param "error". But how can I show the facesmessage in this way?
Another way I tried was to override the messages properties file of Spring Security (overriding the message for the key "badcredentials"), but it didn't work neither (I didn't know how to show the message).
Anyone know how to do it?
Thank you very much in advance.
Upvotes: 0
Views: 1129
Reputation: 1109635
And then in the login page, catch the GET param "error". But how can I show the facesmessage in this way?
This way:
<f:metadata>
<f:viewParam name="error" validator="#{auth.checkErrors}" />
</f:metadata>
<h:messages />
with
public void checkErrors(FacesContext context, UIComponent component, Object value) {
if ("1".equals(value)) {
throw new ValidatorException(new FacesMessage("Invalid credentials"));
}
}
or maybe so:
<f:metadata>
<f:viewParam name="error" value="#{auth.error}" />
<f:event type="preRenderView" listener="#{auth.checkErrors}" />
</f:metadata>
<h:messages />
with
private int error;
public void checkErrors() {
if (error == 1) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Invalid credentials"));
}
}
Either way, this feels pretty hacky :)
Upvotes: 1