在 JavaServer Faces 应用程序中使用受管 Bean 进行身份验证



目标:希望在对用户进行身份验证时在会话中检索和存储用户相关信息(USER 表中超过 5 列),以便我可以在当前会话期间的不同时间点使用用户信息。

方法:我选择在我的JavaServerFaces应用程序中使用托管Bean(LoginBean.java)进行身份验证。 我将检索用户信息并将它们存储在LoginBean.login()方法的会话中。

参考: http://docs.oracle.com/javaee/6/tutorial/doc/glxce.html#glxef

豆代码:

@ManagedBean
@SessionScoped
public class LoginBean {
    private String id;
    private String password;
    public LoginBean() {
        System.out.println("LoginBean() called .....");
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String login() {
        System.out.println("login() invoked .....");
        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest)facesContext.getExternalContext().getRequest();
        try {
            request.login(id, password);
        } catch (ServletException e) {
            facesContext.addMessage(null, new FacesMessage("Login failed."));
            return "error";
        }
        return "home";
    }
    public void logout() {
        System.out.println("logout() invoked .....");
        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest)facesContext.getExternalContext().getRequest();
        try {
            request.logout();
        } catch (ServletException e) {
            facesContext.addMessage(null, new FacesMessage("Logout failed."));
        }
    }
}

网络.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>AuthenticationUsingLoginBean</display-name>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>
   <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>jdbcRealm</realm-name>
        <form-login-config>
            <form-login-page>/login.xhtml</form-login-page>
            <form-error-page>/error.xhtml</form-error-page>
        </form-login-config>
    </login-config>
    <security-constraint>
        <web-resource-collection>       
            <web-resource-name>All resources are restricted</web-resource-name> 
            <url-pattern>/*</url-pattern>
        </web-resource-collection>          
        <auth-constraint>
            <role-name>admin</role-name>            
        </auth-constraint>
    </security-constraint>
</web-app>

登录.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/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">
<h:head>
    <title>Form based authentication with login bean</title>
</h:head>
<h:body>
    <h:form>
        <h:outputLabel for="usernameInput">User ID:</h:outputLabel>
        <h:inputText id="usernameInput" value="#{loginBean.id}" required="true" />
        <h:message for="usernameInput"/>
        <br />
        <h:outputLabel for="passwordInput">Password:</h:outputLabel>
        <h:inputSecret id="passwordInput" value="#{loginBean.password}" required="true" />
        <h:message for="passwordInput" />
        <br />
        <h:commandButton value="Login" action="#{loginBean.login}" />
    </h:form>
</h:body>
</html>

问题我已经启动了新的浏览器窗口并访问了主页(home.xhml)。我被重定向到login.xhtml,这很好。但是,在单击 UI 上的Login按钮时login.xhtmlLoginBean.login()方法不会被调用。

注意 login.xhtml应该是正确的,因为当我注释掉文件中LoginBean.login() <login-config>web.xml该方法被成功调用。 显然,我无法对其进行注释,因为身份验证无法按预期工作。

更新我在 tomcat 的 server.xml 文件中配置了必要的JDBCRealm,并通过使用 j_security_check 实现基于表单的示例身份验证来确保它正常工作。

<Realm className="org.apache.catalina.realm.JDBCRealm"
            driverName="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://localhost/xyz"
            connectionName="root"
            connectionPassword="xxxxx"
            userTable="USER" userCredCol="PASSWORD"
            userRoleTable="USER_ROLE_MPNG" userNameCol="ID" roleNameCol="ROLE_NAME" />

使用的软件:阿帕奇-雄猫-7.0.47JSF 2.1 (Mojarra 2.1.6)

<h:commandButton value="Login" action="#{loginBean.login()}" />

注意登录后的()。 您正在调用一个方法,而不是尝试在 LoginBean 中使用名为 login 的 var 获取/设置。

这不起作用的原因是因为您限制了web.xml中的所有资源。您可以看到您的登录和错误页面,但这并不意味着它周围的一切都可以访问,相反。

溶液

为公共资源添加新的安全约束,如下所示:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Open Resources</web-resource-name>
        <url-pattern>/public/*</url-pattern>
    </web-resource-collection>
</security-constraint>

现在,创建一个新的子文件夹,其中login.xhtmlerror.xhtml,并将其称为 public ,如安全约束中所述。将login.xhtmlerror.xhtml移动到新创建的文件夹中,并相应地调整web.xml中的登录配置。

相关内容

最新更新