I have a JSF 2.2 application with PrimeFaces 5.2 and form-based login in combination with a JBoss security realm using Wildfly 8.2 and PostgreSQL.
This is working fine and absolutely as expected. The problem now is using the above setup with PrimeFaces Mobile . After having entered username and password and clicking the login button nothing happens as I get redirected to the login view again insted of either a redirect to the original requested page or the error page.
Let's start with my mobile login form:
<ui:define name="content">
<pm:content styleClass="content">
<h:form id="loginForm" method="POST" prependId="false"
onsubmit="document.getElementById('loginForm').action = 'j_security_check';">
<p:focus for="j_username"/>
<pm:field>
<p:outputLabel value="Benutzername"></p:outputLabel>
<h:inputText id="j_username" name="j_username" required="true" />
</pm:field>
<pm:field>
<p:outputLabel value="Passwort"></p:outputLabel>
<p:password id="j_password" name="j_password" redisplay="false" required="true" />
</pm:field>
<pm:field>
<p:commandButton id="login" value="Login" ajax="false" />
</pm:field>
</h:form>
</pm:content>
</ui:define>
As mentioned earlier the form definition works with the non-mobile version, for the mobile version I just added tags pm_content
and pm:field
.
When inspecting the generated DOM in Chrome I can see that the rendered mobile version of the page has different ids for the form and input elements than the non-mobile version and also the onsubmit
is missing:
<form id="j_idt6:loginForm" name="j_idt6:loginForm" method="post" action="/MyApp/login.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_idt6:loginForm" value="j_idt6:loginForm">
<span id="j_idt6:j_idt32"></span><script type="text/javascript">$(function(){PrimeFaces.focus('j_idt6:username');});</script><div class="ui-field-contain"><label id="j_idt6:j_idt16" class="ui-outputlabel ui-widget">Benutzername</label><div class="ui-input-text ui-body-inherit ui-corner-all ui-shadow-inset"><input id="j_idt6:username" type="text" name="j_idt6:username"></div></div><div class="ui-field-contain"><label id="j_idt6:j_idt18" class="ui-outputlabel ui-widget">Passwort</label><div id="j_idt6:password" class="ui-input-text ui-body-inherit ui-corner-all ui-shadow-inset ui-input-has-clear"><input data-role="none" id="j_idt6:password" name="j_idt6:password" type="password"><a href="#" class="ui-input-clear ui-btn ui-icon-delete ui-btn-icon-notext ui-corner-all ui-input-clear-hidden"></a></div></div><div class="ui-field-contain"><button id="j_idt6:login" name="j_idt6:login" class="ui-btn ui-shadow ui-corner-all" onclick="" type="submit">Login</button></div><input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="-5673897088131963149:-3654042330506594383" autocomplete="off">
</form>
Now the generated output from the non-mobile login:
<form id="loginForm" name="loginForm" method="post" action="/MyApp/login.xhtml" enctype="application/x-www-form-urlencoded" onsubmit="document.getElementById('loginForm').action = 'j_security_check';">
<input type="hidden" name="loginForm" value="loginForm">
<span id="j_idt11"></span><script type="text/javascript">$(function(){PrimeFaces.focus('j_username');});</script><input id="j_username" type="text" name="j_username"><input id="j_password" type="password" name="j_password" value=""><input id="login" type="submit" name="login" value="Login"><input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="5464337132357101375:3961658655950415709" autocomplete="off">
</form>
If I get it right there seems to be a problem with prepending the ids in the mobile version.
How can I fix this and implement a POST to j_security_check
in PrimeFaces Mobile 5.2?
I was able to tinker a working solution with the hint of @BalusC so that my form now looks like this:
<ui:define name="content">
<pm:content styleClass="content">
<h:form>
<pm:field>
<h:outputLabel for="username" value="Username" />
<h:inputText id="username" value="#{authenticationBean.username}"
required="true" />
<h:message for="username" />
</pm:field>
<pm:field>
<h:outputLabel for="password" value="Password" />
<h:inputSecret id="password" value="#{authenticationBean.password}"
required="true" />
<h:message for="password" />
</pm:field>
<pm:field>
<h:commandButton value="Login" action="#{authenticationBean.login()}" />
</pm:field>
</h:form>
</pm:content>
</ui:define>
The login is now programmatic inside the @ViewScoped
managed bean AuthenticationBean within the login method:
public void login() {
log.info("Login attempt");
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext externalContext = context.getExternalContext();
HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
try {
request.login(username, password);
log.info("Login successful");
externalContext.redirect(originalURL);
} catch (ServletException e) {
// Handle unknown username/password in request.login().
context.addMessage(null, new FacesMessage("Unknown login"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.