I'm learning how to write a JSF application with Shiro but running into some issue with the login page that I made. In debug mode, it seems to be invoking a bean method before I even called it via a HTML command button. The method is not being called in the constructor either. I'm a bit stump as to what's going on.
Backing Bean
package bean;
import javax.faces.*;
import javax.faces.application.FacesMessage;
import javax.faces.bean.*;
import javax.faces.context.FacesContext;
import models.User;
import java.io.*;
import javax.annotation.*;
import org.apache.shiro.*;
import org.apache.shiro.authc.*;
import org.apache.shiro.web.*;
import org.apache.shiro.web.util.*;
import org.primefaces.context.RequestContext;
import javax.persistence.*;
@ManagedBean(name = "loginBacking")
@RequestScoped
public class Login {
private User user = new User();
private String username;
private String password;
private boolean remember;
@ManagedProperty("#{request.requestURL}")
private String url;
@PersistenceContext(unitName = "Builder")
private EntityManager em;
public Login()
{
System.out.print("create bean");
}
// getters and setters
public String userlogin() throws IOException {
try{
System.out.print("trying");
SecurityUtils.getSubject().login(new UsernamePasswordToken(username, password, remember));
Query query = em.createNamedQuery("user.finduser");
query.setParameter("username", username);
user = (User) query.getSingleResult();
return "/builder/builder.xhtml";
}
catch (AuthenticationException e) {
FacesContext.getCurrentInstance().addMessage(username,
new FacesMessage(FacesMessage.SEVERITY_ERROR, "Bad username or password", null));
e.printStackTrace(); // TODO: logger.
}
return "failed.xhtml";
}
}
Login.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHMTL 1.0 Transicational//EN" "http//www.w3.org/TR/xhmtl1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head/>
<h:body>
<h2>Login</h2>
<h:form>
<p:panelGrid columns="3">
<h:outputLabel for="username" value="Username:" />
<h:inputText id="username" required="true" value="#{loginBacking.username}" />
<h:message for="username" />
<h:outputLabel for="password" value="Password" />
<h:inputSecret id="password" required="true" value="#{loginBacking.password}"/>
<h:message for="password" />
<h:outputLabel for="rememberMe" value="Remember Me" />
<h:selectBooleanCheckbox id="rememberMe" value="#{loginBacking.remember}"/>
<h:commandButton value="Login">
<f:param name="action" value="#{loginBacking.userlogin()}"/>
</h:commandButton>
</p:panelGrid>
</h:form>
</h:body>
</html>
In Eclipse's debugging mode, the console log appears to show that the userlogin method is being invoked right the way. The build in broswer doesn't even render the form yet. Once the debugger got to the end of Login bean, then the page would render. When I fill out the form and click on the command button, I'm directed to "login.jsp" which isn't defined in my navigation rules (I have none).