简体   繁体   English

密码错误时,登录表单不显示验证消息

[英]Login form doesn't display validation message when password is wrong

I have a login mechanism consisting of a JSF page + managed bean + EJB, it works fine but the only bug is that i don't see the error message when the password is entered wrong. 我有一个由JSF页面+托管bean + EJB组成的登录机制,它可以正常工作,但是唯一的错误是当密码输入错误时我看不到错误消息。 Any ideas? 有任何想法吗?

When the password is entered wrong this is what i get in the browser: 当密码输入错误时,这是​​我在浏览器中看到的:

在此处输入图片说明

I can avoid this if i don't throw a ValidationException at the catch in the EJB(See EJB code below) but then i don't see any validation message in the form at all when the password is entered wrong. 如果我没有在EJB的陷阱处抛出ValidationException(请参阅下面的EJB代码),但是当密码输入错误时,我根本看不到任何验证消息,可以避免这种情况。

This is the code for the form at the page: 这是页面上表单的代码:

<h:form>
   <p:panel>                
                <h:outputText value="*Em@il:" />
                <h:inputText id="email" value="#{securityController.email}" binding="#{emailComponent}"/>                   
                <br/>
                <h:outputText value="*Lozinka: " />
                <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>

This is the code for the managedBean: 这是managedBean的代码:

    @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("Pogresan email ili lozinka");
            throw new ValidatorException(msg);
        }
        if (passwordInput.length() <= 0 || emailInput.length() <= 0) {
            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;
    }
}

This is the code for the EJB 这是EJB的代码

   @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
        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) {
                            FacesMessage msg = new FacesMessage("Pogresan email ili lozinka");
            throw new ValidatorException(msg); 
        }
        // 4-return false otherwise
        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;
    }
}

Here in the EJB i think i make a mistake if i throw the ValidationException in the catch block, because i think displaying error messages at the front end should be a task for the managed bean. 在EJB中,如果我将ValidationException扔到catch块中,我认为我会犯错,因为我认为在前端显示错误消息应该是托管bean的任务。 I dont understand why the form does not display the error as it does when the fields are empty when the password is wrong(When the email is wrong it displays correctly the validation message). 我不明白为什么密码不正确时,表单不显示错误,因为字段为空(当电子邮件错误时,它正确显示了验证消息)。

Update 更新资料

Changed the saveUserState() method at the EJB to: 将EJB处的saveUserState()方法更改为:

// 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
    List<Object> tmpList = query.getResultList();
    if (tmpList.isEmpty() == false) {
        Role role = (Role) tmpList.get(0);
        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
    return false;
}

The check credentials method: 检查凭证方法:

public boolean checkCredentials(String email, String password) {
    Query checkEmailExists = em
            .createQuery("SELECT COUNT(r) FROM Role r WHERE r.email=:emailparam AND r.password=:passwordparam");
    checkEmailExists.setParameter("emailparam", email);
    checkEmailExists.setParameter("passwordparam", password);
    int matchCounter = 0;
    matchCounter = checkEmailExists.getResultList().size();
    if (matchCounter == 1) {
        return true;
    }
    return false;
}

You should not throw the JSF ValidatorException inside an EJB method, but inside a JSF validate() method. 您不应将JSF ValidatorException扔在EJB方法内,而应扔在JSF validate()方法内。

I'm not sure what went wrong in the EJB which caused this exception, probably getSingleResult() didn't return a single result at all (thus zero or many). 我不确定导致此异常的EJB出了什么问题,可能getSingleResult()根本没有返回单个结果(因此为零或许多)。 You need to change/handle this accordingly, either by using getResultList() or revising your datamodel why the user doesn't have a single role. 您需要通过使用getResultList()或修改您的数据模型来相应地更改/处理该用户为何没有单一角色的原因。 I think you just need getResultList() because you're apparently allowing a null outcome. 我认为您只需要getResultList()因为您显然允许null结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM