JSF基于表单的身份验证+ Managed Bean登录无法正常工作

时间:2014-04-17 03:03:47

标签: eclipse tomcat authentication jsf-2 managed-bean

我希望在Java EE 6 Turorial之后实现托管Bean表单基本身份验证  我必须配置和构建所有必需的元素,例如登录表单,错误页面,web.xml安全配置和Tomcat安全领域(JDBC)。

问题是什么?应该调用Managed Bean中的login()方法的commandButton不起作用,我可以看到构造函数和getter被调用但登录方法和安装者不是。

什么是好奇?如果我从web.xml中删除所有与安全相关的元素,请重新启动应用程序并直接转到login.xhtml表单,确实调用了login()方法。< / p>

结论?如果使用托管bean,JSF实现中必定存在阻止此基于表单的身份验证正常工作的内容。

注意:常规的j_security_check基于表单的身份验证(不使用JSF)工作正常。

任何想法?

login.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 lang="en" xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
<f:view>
    <h:head>
        <title>Login Form</title>
    </h:head>
    <h:body>
        <h2>Hello, please log in:</h2>
        <h:form id="loginForm">
            <h:messages style="color:red;margin:8px;" />
            Username: <h:inputText value="#{loginBean.username}" />
            <br />
            Password: <h:inputSecret value="#{loginBean.password}" />
            <br />
            <h:commandButton id="loginButton" value="Login" action="#{loginBean.login}" />
        </h:form>
    </h:body>
</f:view>
</html>

LoginBean.java

package src;

import java.io.Serializable;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

@ManagedBean
@SessionScoped
public class LoginBean implements Serializable  {

    /**
     * 
     */
    private static final long serialVersionUID = 2951813936936766650L;

    public LoginBean() {
        System.out.println("LoginBean()");
    }

    private String username;
    private String password;

    public String getUsername() {
        System.out.println("getUsername() returning: " + this.username);
        return this.username;
    }

    public void setUsername(String username) {
        System.out.println("setUserName(" + username + ")");
        this.username = username;
    }

    public String getPassword() {
        System.out.println("getPassword() returning: " + this.password);
        return this.password;
    }

    public void setPassword(String password) {
        System.out.println("setPassword(" + password + ")");
        this.password = password;
    }

    public String dummy() {
        System.out.println("dummy()");
        return "dummy";
    }

    public String login() {
        System.out.println("login()");
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        try {
            request.login(this.username, this.password);
        } catch (ServletException e) {
            e.printStackTrace();
            context.addMessage(null, new FacesMessage("Login failed."));
            return "error";
        }
        return "index";
    }

    public void logout() {
        System.out.println("logout()");
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        try {
            request.logout();
        } catch (ServletException e) {
            e.printStackTrace();
            context.addMessage(null, new FacesMessage("Logout failed."));
        }
    }

}

的web.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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>FormBasedManagedBeanAuth</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>/faces/*</url-pattern>
    </servlet-mapping>
    <context-param>
        <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
    </context-param>
    <context-param>
        <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
        <param-value>resources.application</param-value>
    </context-param>
    <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener>
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
    <security-constraint>
        <display-name>Tomcat7FormBasedJAAS</display-name>
        <web-resource-collection>
            <web-resource-name>secured</web-resource-name>
            <description />
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <description />
            <role-name>user</role-name>
        </auth-constraint>
    </security-constraint>
    <login-config>
        <auth-method>FORM</auth-method>
        <form-login-config>
            <form-login-page>/faces/login.xhtml</form-login-page>
            <form-error-page>/faces/error.xhtml</form-error-page>
        </form-login-config>
    </login-config>
    <security-role>
        <description />
        <role-name>user</role-name>
    </security-role>
</web-app>

server.xml(tomcat,fragment)

<Realm className="org.apache.catalina.realm.JDBCRealm"
    connectionName="database"
    connectionPassword="password"
    connectionURL="jdbc:mysql://localhost:3306/database"
    driverName="com.mysql.jdbc.Driver"
    roleNameCol="roleName"
    userCredCol="password"
    userNameCol="userName"
    userRoleTable="user_role"
    userTable="user"/>

2 个答案:

答案 0 :(得分:1)

我不是这方面的专家,因为我遇到了同样的问题而遇到了这个问题。我最终做的是在web.xml中有一个安全区域和一个不安全的区域,就像这样......

<security-constraint>
    <web-resource-collection>
        <web-resource-name>SecureArea</web-resource-name>
        <url-pattern>/secure/*</url-pattern>
    </web-resource-collection>

然后我有以下用于登录的URL /WAR/login.xhtml 以及我的所有其他应用程序 / WAR /安全/ *

这样可以执行loginBean。 工作就像一个魅力。我不确定是否有更好的方法,但这对我有用。

答案 1 :(得分:0)

您的login.xhtml是安全区域,因此未经授权的用户不得访问任何bean。

您可以按照自己的答案进行操作,也可以定义“公共”区域, 让其他一切安全:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Public Area</web-resource-name>
        <description>Public Area</description>
        <url-pattern>/public/*</url-pattern>
    </web-resource-collection>
</security-constraint>

现在您将login.xhtml移动到public / login.xhtml并更正web.xml中的login-config:

<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>ALMGCCAdminDB</realm-name>
    <form-login-config>
        <form-login-page>/public/login.xhtml</form-login-page>
        <form-error-page>/public/error.xhtml</form-error-page>
    </form-login-config>
</login-config>
相关问题