I need to check several fields for the login page (many fields are checked at once by the same method). I do not know how to implement it correctly. I follow the example I found at: http://balusc.blogspot.com/2007/12/validator-for-multiple-fields.html
I am a bit confused about the JSF part. Can someone give me a hand that I am missing?
Page:
<h:form> <p:panel> <h:outputText value="* Em@il :" /> <h:inputText id="email" value="#{securityController.email}" required="true" /> <br /> <h:outputText value="*Password: " /> <h:inputSecret id="password" value="#{securityController.password}" required="true"> <f:validator validatorId="loginValidator" /> </h:inputSecret> <br /> <span style="color: red;"><h:message for="password" showDetail="true" /></span> <br /> <h:commandButton value="Login" action="#{securityController.logIn()}" /> </p:panel> </h:form>
This is a managed bean using a validation method:
@ManagedBean @RequestScoped public class SecurityController implements Validator { @EJB private IAuthentificationEJB authentificationEJB; private String email; private String password; private String notificationValue; public String logIn() { if (authentificationEJB.saveUserState(email, password)) { notificationValue = "Dobro dosli"; return "main.xhtml"; } else { return ""; } } public void validate(FacesContext context, UIComponent validate, Object value) { String emailInput = (String) value; String emailPatternText = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)" + "*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; Pattern emailPattern = null; Matcher emailMatcher = null; emailPattern = Pattern.compile(emailPatternText); emailMatcher = emailPattern.matcher(emailInput); String inputFromField = (String) value; String alphanumericPattern = "^[a-zA-Z0-9]+$"; Pattern passwordPattern = null; Matcher passwordMatcher = null; passwordPattern = Pattern.compile(alphanumericPattern); passwordMatcher = passwordPattern.matcher(inputFromField); if (!emailMatcher.matches() && !passwordMatcher.matches()) { if (authentificationEJB.checkCredentials(email, password) == false) { FacesMessage msg = new FacesMessage( "Pogresan email ili lozinka"); throw new ValidatorException(msg); } } } public String getEmail() { return email; } public String getPassword() { return password; } public void setEmail(String email) { this.email = email; } public void setPassword(String password) { this.password = password; } public String getNotificationValue() { return notificationValue; } public void setNotificationValue(String notificationValue) { this.notificationValue = notificationValue; } }
EJB that interacts with the database to verify credentials:
@Stateful(name = "ejbs/AuthentificationEJB") public class AuthentificationEJB implements IAuthentificationEJB { @PersistenceContext private EntityManager em; // Login public boolean saveUserState(String email, String password) { // 1-Send query to database to see if that user exist Query query = em .createQuery("SELECT r FROM Role r WHERE r.email=:emailparam " + "AND r.password=:passwordparam"); query.setParameter("emailparam", email); query.setParameter("passwordparam", password); // 2-If the query returns the user(Role) object, store it somewhere in // the session Role role = (Role) query.getSingleResult(); if (role != null && role.getEmail().equals(email) && role.getPassword().equals(password)) { FacesContext.getCurrentInstance().getExternalContext() .getSessionMap().put("userRole", role); // 3-return true if the user state was saved System.out.println(role.getEmail() + role.getPassword()); return true; } // 4-return false otherwise System.out.println(role.getEmail() + role.getPassword()); return false; } // Logout public void releaseUserState() { // 1-Check if there is something saved in the session(or wherever the // state is saved) if (!FacesContext.getCurrentInstance().getExternalContext() .getSessionMap().isEmpty()) { FacesContext.getCurrentInstance().release(); } // 2-If 1 then flush it } // Check if user is logged in public boolean checkAuthentificationStatus() { // 1-Check if there is something saved in the session(This means the // user is logged in) if ((FacesContext.getCurrentInstance().getExternalContext() .getSessionMap().get("userRole") != null)) { // 2-If there is not a user already loged, then return false return true; } return false; } @Override public boolean checkCredentials(String email, String password) { Query checkEmailExists = em .createQuery("SELECT COUNT(r.email) FROM Role r WHERE " + "r.email=:emailparam AND r.password=:passwordparam"); checkEmailExists.setParameter("emailparam", email); checkEmailExists.setParameter("passwordparam", password); long matchCounter = 0; matchCounter = (Long) checkEmailExists.getSingleResult(); if (matchCounter > 0) { return true; } return false; } }
Update
Removed LoginValidator
Modified managed bean:
@ManagedBean @RequestScoped public class SecurityController { @EJB private IAuthentificationEJB authentificationEJB; private String email; private String password; private String notificationValue; public String logIn() { if (authentificationEJB.saveUserState(email, password)) { notificationValue = "Dobro dosli"; return "main.xhtml"; } else { return ""; } } public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { UIInput emailComponent = (UIInput) component.getAttributes().get( "emailComponent"); String email = ""; String password = ""; email = (String) emailComponent.getValue(); password = (String) value; String emailInput = email; String emailPatternText = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)" + "*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; Pattern emailPattern = null; Matcher emailMatcher = null; emailPattern = Pattern.compile(emailPatternText); emailMatcher = emailPattern.matcher(emailInput); String passwordInput = password; String alphanumericPattern = "^[a-zA-Z0-9]+$"; Pattern passwordPattern = null; Matcher passwordMatcher = null; passwordPattern = Pattern.compile(alphanumericPattern); passwordMatcher = passwordPattern.matcher(passwordInput); if (!emailMatcher.matches() && !passwordMatcher.matches()) { if (authentificationEJB.checkCredentials(emailInput, passwordInput) == false) { FacesMessage msg = new FacesMessage( "Pogresan email ili lozinka"); throw new ValidatorException(msg); } } if (emailInput == null || passwordInput == null) { FacesMessage msg = new FacesMessage("Zaboraviliste nesto"); throw new ValidatorException(msg); } if (passwordInput.length() <= 0 || emailInput.length() <= 0) { FacesMessage msg = new FacesMessage("Zaboraviliste nesto"); throw new ValidatorException(msg); } }
Login form:
<h:form> <p:panel> <h:outputText value="* Em@il :" /> <h:inputText id="email" value="#{securityController.email}" binding="#{emailComponent}" /> <br /> <h:outputText value="*Password: " /> <h:inputSecret id="password" value="#{securityController.password}" validator="#{securityController.validate}"> <f:attribute name="emailComponent" value="#{emailComponent}" /> </h:inputSecret> <br /> <span style="color: red;"><h:message for="password" showDetail="true" /></span> <br /> <h:commandButton value="Login" action="#{securityController.logIn()}" /> </p:panel> </h:form>
Changed saveUserState () Method in EJB:
// Login public boolean saveUserState(String email, String password) { // 1-Send query to database to see if that user exist Query query = em .createQuery("SELECT r FROM Role r WHERE r.email=:emailparam " + "AND r.password=:passwordparam"); query.setParameter("emailparam", email); query.setParameter("passwordparam", password); // 2-If the query returns the user(Role) object, store it somewhere in // the session try { Role role = (Role) query.getSingleResult(); if (role != null && role.getEmail().equals(email) && role.getPassword().equals(password)) { FacesContext.getCurrentInstance().getExternalContext() .getSessionMap().put("userRole", role); // 3-return true if the user state was saved System.out.println(role.getEmail() + role.getPassword()); return true; } } catch (Exception e) { // This fix the bug that does not display the message when wrong // password! FacesMessage msg = new FacesMessage("Pogresan email ili lozinka"); throw new ValidatorException(msg); } // 4-return false otherwise return false; }