繁体   English   中英

基于JSF表单的身份验证+托管Bean登录不起作用

[英]JSF Form Based Authentication + Managed Bean login not working

我要实现Java EE 6 Turorial之后的Managed Bean Form Base Authentication,我必须配置并构建所有必需的元素,例如登录表单,错误页面,web.xml安全配置和Tomcat安全领域( JDBC)。

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

有什么好奇吗? 如果我从web.xml中删除了所有与安全性相关的元素,请重新启动应用程序并直接进入login.xhtml,因为确实调用了login()方法。

结论? 如果使用托管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,片段)

<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"/>

我在任何方面都不是该领域的专家,遇到了同样的问题,因此遇到了这一问题。 我最终要做的就是像这样在web.xml中有一个安全区域和一个非安全区域...

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

因此,对于登录/WAR/login.xhtml和我的所有其他应用程序/ WAR / secure / *,我都有以下URL

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

您的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>

暂无
暂无

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

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