I have a site with a login form that looks like this.
<h:panelGrid columns="3">
<p:outputLabel value="Username:" for="username"/>
<p:inputText id="username" autocomplete="off" />
<p:message for="username"/>
<p:outputLabel value="Password:" for="password"/>
<p:password id="password" />
<p:message for="password"/>
</h:panelGrid>
We are using Spring security to validate passwords, and when I throw a break point in Spring's UsernamePasswordAuthenticationFilter, the password is always blank when using Safari's autofill password feature. This causes the login to fail.
For reference, here is the portion of Spring's code that my break point is located in
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = obtainUsername(request);
String password = obtainPassword(request);
if (username == null) {
username = "";
}
//My breakpoint is here, but password = "" even though we have a user name
if (password == null) {
password = "";
}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
I'm at a total loss as to what I can check to solve this. This password issue only affects Safari. Other browsers such as IE, Chrome, FF work just fine.
Ok. I found the problem!
<p:defaultCommand target="ndaLoginButton" />
<h:panelGroup styleClass="errorText centered" rendered="#{authenticationBean.failedLogin}">
<h:outputText rendered="#{authenticationBean.isFailedLogin() and not authenticationBean.lockedAccount}"
value="Invalid username or password. Please try again." />
<h:outputText rendered="#{authenticationBean.lockedAccount}"
value="Account locked. You can reset account password below." />
</h:panelGroup>
#{authenticationBean.setFailedLogin(false)}
<h:form id="loginDialogForm" prependId="false">
<h:panelGrid columns="2" styleClass="ndaLoginDialogTable" columnClasses="ndaLoginDialogTop, ndaLoginDialogTop">
<h:panelGroup>
<h:panelGrid columns="3">
<p:outputLabel value="Username:" for="username"/>
<p:inputText id="username" autocomplete="off" />
<p:message for="username"/>
<p:outputLabel value="Password:" for="password"/>
<p:password id="password" autocomplete="off" />
<p:message for="password"/>
</h:panelGrid>
<input type="submit" style="visibility: hidden;" onclick="$j('#ndaLoginButton').click();"/>
<input type="hidden" id="loginDialogSubmit" name="loginDialogSubmit" value="loginDialogSubmit" />
<input type="hidden" id="loginDialogRedirect" name="loginDialogRedirect" />
</h:panelGroup>
<h:panelGroup>
<p:commandButton id="ndaLoginButton" value="NDA Login" type="submit" action="#{loginDialogPageBean.login}"
ajax="false" onclick="ndar.showPreloader()"/>
</h:panelGroup>
</h:panelGrid>
</h:form>
The problem is the <p:defaultCommand> tag. This tag is used to specify which control gets pressed when the user hits the enter key on the keyboard. What was happing was that Safari was sending a virtual enter key press prior to populating the password field on the form. I solved the problem by simply removing this <p:defaultCommand> tag since it wasn't necessary anyway.
Related
Hi i am working on jsf f:ajax i it worked for me when i have done the validations with in the page using ajax. but now i wanted to get the response from a Managed bean method that is called on as a ajax listener.
I m not able to get the response back in any of the format.any body please help me.
Here is the code
register.xhtml
<h:outputText value="Full Name:" escape="false" />
<h:inputText value="#{display.user}" required="true" label="User ID"
id="username">
<f:validateRegex pattern="[A-Za-z]*[\.][A-Za-z]*"></f:validateRegex>
<!-- <f:validator validatorId="com.jason.jsf.custom.Myvalidator"></f:validator> -->
<f:ajax render="usernameMessage outputMessage" event="blur" />
</h:inputText>
<h:message id="usernameMessage" for="username" style="color:red;" />
<h:outputText value="Email:" escape="false" />
<h:inputText value="#{display.email}" required="true" id="EmailID"
label="Email ID"
validatorMessage="#{display.email} is not valid email">
<f:validateRegex
pattern="[\w\.-]*[a-zA-Z0-9_]#[\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]" />
<f:ajax render="EmailIDmsg" event="blur"
listener="#{display.getMessage}" onevent="fun" />
</h:inputText>
<h:message id="EmailIDmsg" for="EmailID" />
script.js
function fun(e){
var xmlDoc,x,txt,i;
alert("text"+e.responseText);
alert("XML"+e.responseXML);
}
Method in Display.java a managed bean with name display contians a field email with all the setters and getters
public String getMessage(AjaxBehaviorEvent e) throws InterruptedException {
System.out.println("hai this is listener method");
System.out.println(e.getComponent().getId());
System.out.println(email);
return email;
}
I using JSF 2.0 Mojarra 2.0.3
I have a number of questions that are related to each other so the title of question may not be appropriate. Sorry for this.
I want to have a p:inputText and p:commandButton in a p:dialog such that when the user presses that button or presses enter key the value entered in the
p:inputText will be saved in the database. To do this I followed this example http://www.primefaces.org/showcase/ui/dialogForm.jsf and it worked fine when I tried it in a seperate .xhtml file in which there were no other dialogs or command buttons.
<h:body>
<h:form id="form">
<p:commandButton id="showDialogButton" type="button" value="Show" onclick="PF('dlg').show()" />
<p:dialog header="Enter FirstName" widgetVar="dlg" resizable="false">
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="firstname" value="Firstname:" />
<p:inputText id="firstname" value="#{subjectController.attributeValue}" />
</h:panelGrid>
<p:commandButton id="submitButton" value="Submit" update=":form:display :form:firstname" action="#{subjectController.saveUpdateSubjectAttributeValue}" oncomplete="PF('dlg').hide();"/>
<p:defaultCommand target="submitButton"></p:defaultCommand>
</p:dialog>
<p:outputPanel id="display" style="display:block;margin-top:10px;">
<h:outputText id="name" value="Hello #{subjectController.attributeValue}" rendered="#{not empty subjectController.attributeValue}"/>
</p:outputPanel>
</h:form>
</h:body>
The .xhtml file that I originally have contains a number of other dialogs and command buttons. When i used the same code in that file it does not work properly. By not working properly I mean to say that when enter key or submit button is pressed the value entered by the user is not set in the corresponding setter of the inputText in the managed bean. To call the setter before pressing the enter key or button I need to use p:ajax inside p:inputText tag. I tried to use p:ajax events such as "mouseout", "blur", "change" etc. They work for the submit button but not for the enter key. Then I tried "keypress" and "keyup" etc. They worked for both but the setter for the value in the p:inputText was called on each key press which was not desired.
My first question:
If the sample code is working fine in a separate file why doesn't it work when I have other dialogs or commandbuttons in the same file. In both the cases I am using the same managed bean. What is the difference?
Assuming that the problem may be caused using more than one dialogs in the same file, I thought of declaring these dialogs in separate files such that I have
A.xhtml , B.xhtml, C.xhtml pages which contain the actual content and whenever I need to open a dialog the required dialog is located in file such as dialog.xhtml. Being a beginner in JSF, Primefaces and Ajax I was confused about how to do this. Searching on the internet I found this post relevant PrimeFaces dialog lazy loading (dynamic="true") does not work?. But in this case, p:dialog is located on the same page but the content contained in this dialog is located in another file which is included using ui:include. I tried this but it shows the same behavior.
My Second Question:
Is there any way to programmatically open a dialog from another file e.g. if I have a p:commandButton in A.xhtml and p:dialog in the same file I can do this using
<p:commandButton id="submitButton" value="Submit" update=":form:display :form:firstname" action="#{subjectController.saveUpdateSubjectAttributeValue}" oncomplete="PF('dlg').hide();"/>
and in the corresponding subjectController I have
saveUpdateSubjectAttributeValue(){
RequestContext context = RequestContext.getCurrentInstance();
context.openDialog("openDialog");
// or
context.execute("openDialog");
}
But what if the "openDialog" is located in B.xhtml?
What I understand, I can use enclose p:dialog in a ui:composition (in B.xhtml) and and use ui:include in A.xhtml. But I am confused in how and where to call openDialog.open() or openDialog.hide()?
I've tried to replicate the behavior you posted here and I believe that the cause is probably somewhere else as mentioned by Yipitalp.
Anyway, here are the sample code I used that might do what you expect (Primefaces 4):
The Managed Bean
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.context.RequestContext;
#ManagedBean
#ViewScoped
public class DialogBean implements Serializable {
private String attribute1;
private String attribute2;
private String attribute3;
private String dlg;
public void openDialog() {
RequestContext context = RequestContext.getCurrentInstance();
context.execute("PF('" + dlg + "').show()");
}
public String getAttribute1() {
return attribute1;
}
public void setAttribute1(String attribute1) {
this.attribute1 = attribute1;
}
public String getAttribute2() {
return attribute2;
}
public void setAttribute2(String attribute2) {
this.attribute2 = attribute2;
}
public String getAttribute3() {
return attribute3;
}
public void setAttribute3(String attribute3) {
this.attribute3 = attribute3;
}
public String getDlg() {
return dlg;
}
public void setDlg(String dlg) {
this.dlg = dlg;
}
}
The view
Note that I use a different form for every dialog in the view.
<h:form>
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="dlg" value="Dlg:" />
<p:selectOneMenu id="dlg" value="#{dialogBean.dlg}" >
<f:selectItem itemLabel="dlg1" itemValue="dlg1" />
<f:selectItem itemLabel="dlg2" itemValue="dlg2" />
<f:selectItem itemLabel="dlg3" itemValue="dlg3" />
</p:selectOneMenu>
</h:panelGrid>
<p:commandButton id="submitButton" value="Submit" action="#{dialogBean.openDialog}"/>
<p:defaultCommand target="submitButton" />
</h:form>
<p:button id="showDialogButton1" value="Show 1" onclick="PF('dlg1').show();
return false;" />
<p:button id="showDialogButton2" value="Show 2" onclick="PF('dlg2').show();
return false;" />
<p:button id="showDialogButton3" value="Show 3" onclick="PF('dlg3').show();
return false;" />
<br />
<p:dialog header="Enter FirstName" widgetVar="dlg1" resizable="false">
<h:form>
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="firstname" value="Firstname:" />
<p:inputText id="firstname" value="#{dialogBean.attribute1}" />
</h:panelGrid>
<p:commandButton id="submitButton" value="Submit" oncomplete="PF('dlg1').hide();"/>
<p:defaultCommand target="submitButton" />
</h:form>
</p:dialog>
<p:dialog header="Enter FirstName" widgetVar="dlg2" resizable="false">
<h:form>
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="firstname" value="Firstname:" />
<p:inputText id="firstname" value="#{dialogBean.attribute2}" />
</h:panelGrid>
<p:commandButton id="submitButton" value="Submit" oncomplete="PF('dlg2').hide();"/>
<p:defaultCommand target="submitButton" />
</h:form>
</p:dialog>
<p:dialog header="Enter FirstName" widgetVar="dlg3" resizable="false">
<h:form>
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="firstname" value="Firstname:" />
<p:inputText id="firstname" value="#{dialogBean.attribute3}" />
</h:panelGrid>
<p:commandButton id="submitButton" value="Submit" oncomplete="PF('dlg3').hide();"/>
<p:defaultCommand target="submitButton" />
</h:form>
</p:dialog>
<p:outputPanel autoUpdate="true" style="border: 1px solid black; margin-top:10px;">
Value 1:
<h:outputText id="v1" value="#{dialogBean.attribute1}" />
<br />
Value 2:
<h:outputText id="v2" value="#{dialogBean.attribute2}" />
<br />
Value 3:
<h:outputText id="v3" value="#{dialogBean.attribute3}" />
</p:outputPanel>
I hope that will give you some clue!
I was able to solve major part of my problems using DialogFramework. I have a Menu.xhtml page, it contains p:tieredMenu in p:layoutUnit with position="north" using which I select which page to open. Depending on the selection, the p:layoutUnit with position="center" includes that page using ui:include. The Menu.xhtml page contains a h:form with id="form" inside h:body and everything else is placed inside this h:form. There are a number of pages that can be included inside the <p:layoutUnit position="center"> depending upon the selection. One of them is Person.xhtml(containing everything enclosed inside a ui:composition ). It contains a p:fieldset. Inside p:fieldset there are 3 p:dataTable. Outside this p:fieldset I have placed 3 p:contextMenu one for each of those datatables. Inside one of those p:contextMenu I have placed
<p:menuitem value="Update" actionListener="#{controller.updateAttributeValue}" />
and the corresponding function contains
public void updateAttributeValue(){
System.out.println("update attribute value");
RequestContext context = RequestContext.getCurrentInstance();
context.openDialog("selectCar2");
this.attributeValue = null;
}
selectCar2.xhtml contains the following code
<h:body>
<h:form>
<h:panelGrid id="updateAttributeValuePanel" columns="2" style="margin-bottom:10px">
<h:outputLabel value="Attribute Value " />
<p:inputText id="attributeValue" value="#{controller.attributeValue}" required="true" />
</h:panelGrid>
<p:commandButton id="saveUpdateAttributeValue" value="Submit" actionListener="#{controller.saveUpdateAttributeValue}"
/>
<p:commandButton id="cancelUpdateAttributeValue" value="Cancel "
action="#{controller.cancelUpdateAttributeValue}"
/>
<p:defaultCommand target="saveUpdateAttributeValue" />
</h:form>
</h:body>
The corresponding save function is as follows
public void saveUpdateAttributeValue(){
RequestContext context = RequestContext.getCurrentInstance();
System.out.println("this.attributevalue = " + this.attributeValue);
////save value in database
this.attributeValue = null;
context.update(":form:resourceAttributeValueDataTable");
//also tried context.update("resourceAttributeValueDataTable");
context.closeDialog(this.attributeValue);
}
and
public void cancelUpdateAttributeValue(){
RequestContext context = RequestContext.getCurrentInstance();
context.closeDialog(this.attributeValue);
System.out.println("cancel update attribute value");
this.attributeValue = null;
System.out.println("this.attributevalue = " + this.attributeValue);
}
The dialog opens and the value is successfully saved in the database. The only problem now is that the corresponding datatable is not updated and I need to refresh the page to see the updated value. previously my dialog was also in the same page outside the p:fieldset and I was not using h:form inside dialog so I was updating the datatable as
<p:commandButton id="saveUpdateAttributeValue" value="Submit" actionListener="#{controller.saveUpdateAttributeValue}"
update = ":form:attributeValueDataTable "/>
But now they are in two different files and two different forms so I am not sure how to update in this case? I have tried to use
context.update(":form:resourceAttributeValueDataTable");
//or
context.update("resourceAttributeValueDataTable");
but the datatable is not updated. Any help will be highly appreciated.
I have implemented a custom validator for my screen referring to the example given here.
But in my case, my validator method is not invoked if I don't enter any values in any of the field. So the check for empty fields is never done. The required messages are displayed everytime.
If I removed the required attributes, even in that case the validator is invoked only if the fields have some value in them. How do I get all my validations to be done in the validator class?
My xhtml:
<h:form>
<p:messages id="message" closable="true"/>
<h:panelGrid columns="3" id="changePassPanel">
<h:outputLabel for="pwd0" value="Current password :" />
<p:password id="pwd0" value="#{homeBean.password1}">
<f:validator validatorId="PasswordValidator"></f:validator>
<f:attribute name="pwd1" value="#{pwd1}" />
<f:attribute name="pwd2" value="#{pwd2}" />
</p:password>
<h:outputLabel for="pwd1" value="New password :" />
<p:password id="pwd1" value="#{homeBean.password2}" binding="#{pwd1}"/>
<h:outputLabel for="pwd2" value="Confirm new password :" />
<p:password id="pwd2" binding="#{pwd2}"/>
</h:panelGrid>
<p:commandButton id="saveButton" value="Save" validateClient="true"/>
</h:form>
i want to implement a validation for a username. The 'normal' way to do it
is something like that:
<h:outputText for="username" value="Username:" />
<p:inputText id="username" value="#{registerService.username}" >
<f:validator binding="#{usernameValidator}" />
</p:inputText>
<p:message for="username" />
<p:commandButton type="submit" value="Submit" action="#{registerService.addUser}" ajax="false" update="panel" validateClient="true" />
But what i now want to do is to validate the username everytime
the user presses a key in the username inputText without pressing
the commandButton.
So each character should trigger the validation and should update
the messages field for username to show the user instantly if the
username is already present in database or not.
How can i do that?
Found:
Ajax Listener
This triggers the validation!
<h:inputText id="foo" value="#{bean.foo}">
<f:ajax event="keyup" execute="#this" render="fooMessage" />
<f:validator validatorId="fooValidator" />
</h:inputText>
<h:message id="fooMessage" for="foo" />
I am trying to recharge the same primefaces component after an successful login with ajax behaviour, but I don't know how to do this. The recharged component must show the complete name of the user which is recovered by an hibernate dao from the DB and the input boxes for user and password must desappear.
View :
<h:head>
<title>header layout</title>
</h:head>
<h:body>
<h:panelGrid id="loginPanelGrid">
<h:form id="loginForm">
<h:outputLabel for="username" value="Username:" />
<p:inputText value="#{loginManagedBean.username}" id="username" required="true" label="username" />
<h:outputLabel for="password" value="Password:" />
<p:password value="#{loginManagedBean.password}" id="password" required="true" label="password" />
</h:form>
<f:facet name="footer">
<p:commandButton id="loginButton" value="Login" update="okLoginPanelGrid" action="#{loginManagedBean.login(actionEvent)}"/>
</f:facet>
</h:panelGrid>
<p:panelGrid id="okLoginPanelGrid">
<h:outputText id="clienteLogado" value="#{loginManagedBean.loggedClient}" />
</p:panelGrid>
</h:body>
Bean :
#ManagedBean
#SessionScoped
public class LoginManagedBean implements Serializable{
private String username;
private String password;
private Cliente loggedClient;
#ManagedProperty(value="#{clienteDAO}")
private ClienteDAO clienteDAO;
public void login(ActionEvent actionEvent){
RequestContext context = RequestContext.getCurrentInstance();
if( (this.getUsername() != null && !this.getUsername().isEmpty()) &&
(this.getPassword() != null && !this.getPassword().isEmpty()) ){
List<Cliente> clienteLogin = clienteDAO.comprobarLogin(username, password);
if(clienteLogin != null && clienteLogin.size() > 0){
loggedClient = new Cliente();
for(Cliente client : clienteLogin){
loggedClient.setCliente_nombre(client.getCliente_nombre());
loggedClient.setCliente_apellido1(client.getCliente_apellido1());
loggedClient.setCliente_apellido2(client.getCliente_apellido2());
}
}else{
System.out.println("**** There are NO CLIENTS for this user and password selected ****");
}
}else{
System.out.println("**** user or password NOT RECOVERED ****");
}
}
You should move your h:form to encapsulate the p:commandButton. That prevent your p:commandButton to submit anything to the bean. You should add it like this :
<h:body>
<h:panelGrid id="login-panel">
<h:form rendered="#{loginManagedBean.loggedClient eq null}">
<h:panelGroup id="loginPanelGrid">
<h:outputLabel for="username" value="Username:" />
<p:inputText value="#{loginManagedBean.username}" id="username" required="true" label="username" />
<h:outputLabel for="password" value="Password:" />
<p:password value="#{loginManagedBean.password}" id="password" required="true" label="password" />
<f:facet name="footer">
<p:commandButton id="loginButton" value="Login" update="login-panel" action="#{loginManagedBean.login(actionEvent)}"/>
</f:facet>
</h:panelGroup>
</h:form>
<p:panelGroup rendered="#{loginManagedBean.loggedClient ne null}" id="okLoginPanelGrid">
<h:outputText id="clienteLogado" value="#{loginManagedBean.loggedClient.client_name}" />
</p:panelGroup>
</h:panelGrid>
</h:body>
Not related :
I would also say the shorter a bean lives, the better your memory usage will be. In that way, the bean LoginManagedBean don't need to be SessionScoped, it could even be only RequestScoped if you move your property loggedClient to a SessionScoped attribute.