1

我正在尝试向基于 JSF 2 的应用程序添加身份验证。我是按照教程开始的。

以下是我的数据库中的导出:

CREATE TABLE `authentication_groups` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(45) NOT NULL,
  `description` varchar(255) default NULL,
  `create_time` timestamp NULL default CURRENT_TIMESTAMP,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `authentication_groups` VALUES (1,'Guest','Anonymous user','2012-07-18 13:54:34'),(2,'Member','Standart user','2012-07-18 13:54:34'),(3,'Admin','Administrator','2012-07-18 13:54:34');

CREATE TABLE `users` (
  `id` int(11) NOT NULL auto_increment,
  `username` varchar(45) NOT NULL,
  `password` varchar(128) NOT NULL,
  `first_name` varchar(45) default NULL,
  `last_name` varchar(45) default NULL,
  `create_time` timestamp NULL default CURRENT_TIMESTAMP,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `username_UNIQUE` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

INSERT INTO `users` VALUES (1,'admin','8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918','Samuil','Yanovski','2012-07-24 06:41:56');

CREATE TABLE `users_authentication_groups_link` (
  `id` int(11) NOT NULL auto_increment,
  `user_id` int(11) NOT NULL,
  `authentication_group_id` int(11) NOT NULL,
  `create_time` timestamp NULL default CURRENT_TIMESTAMP,
  PRIMARY KEY  (`id`),
  KEY `uag_link_users_fk` (`user_id`),
  KEY `uag_link_authentication_groups_fk` (`authentication_group_id`),
  CONSTRAINT `uag_link_authentication_groups_fk` FOREIGN KEY (`authentication_group_id`) REFERENCES `authentication_groups` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `uag_link_users_fk` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

INSERT INTO `users_authentication_groups_link` VALUES (1,1,3,'2012-07-24 06:42:25');

SELECT `u`.`username` AS `username`,
       `u`.`password` AS `password`,
       `g`.`name`     AS `name`
FROM   ( (`observer`.`users_authentication_groups_link` `ug`
          JOIN `observer`.`users` `u`
            ON(( `u`.`id` = `ug`.`user_id` )))
         JOIN `observer`.`authentication_groups` `g`
           ON(( `g`.`id` = `ug`.`authentication_group_id` )));

我有一个用户名“admin”和密码“admin”(使用 SHA-256 和十六进制编码加密)的用户。

我在 Glassfish 管理控制台中创建了一个 JDBC 连接池,它正在成功地 ping 数据库。我已将此池分配给名为“jdbc/observer”的 JDBC 资源。之后在Configuration -> server-config -> Security -> Realms中,我使用以下配置创建了“ObserverRealm”:

在此处输入图像描述

这是我的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <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>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>jdbcRealm</realm-name>
        <form-login-config>
            <form-login-page>/faces/login.xhtml</form-login-page>
            <form-error-page>/faces/loginError.xhtml</form-error-page>
        </form-login-config>
    </login-config>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Admin</web-resource-name>
            <url-pattern>/faces/private/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>Admin</role-name>
        </auth-constraint>
    </security-constraint>
</web-app>

glassfish-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
  <security-role-mapping>
    <role-name>Admin</role-name>
    <principal-name>Admin</principal-name>
    <group-name>Admin</group-name>
  </security-role-mapping>
  <class-loader delegate="true"/>
  <jsp-config>
    <property name="keepgenerated" value="true">
      <description>Keep a copy of the generated servlet class' java code.</description>
    </property>
  </jsp-config>
</glassfish-web-app>

login.xml非常基本:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                template="/templates/master.xhtml"
                xmlns:h="http://java.sun.com/jsf/html">

    <ui:define name="content">
        <p>Login to access secure pages:</p>  
        <h:messages />  
        <h:form id="loginForm">  
            <h:panelGrid columns="2">  
                <h:outputLabel for="username" value="Username:" />  
                <h:inputText id="username" value="#{authBackingBean.username}" />  

                <h:outputLabel for="password" value="Password:" />  
                <h:inputSecret id="password" value="#{authBackingBean.password}" />  

                <h:commandButton id="loginButton" value="Login" action="#{authBackingBean.login}" />  
            </h:panelGrid>  
        </h:form> 
    </ui:define>
</ui:composition>

AuthBackingBean

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package yanovski.observer.jsf;

import java.security.Principal;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

/**
 *
 * @author Intuitiv-06
 */
@ManagedBean(name = "authBackingBean")
@RequestScoped
public class AuthBackingBean {

    private static final Logger log = Logger.getLogger(AuthBackingBean.class.getName());
    private String username;
    private String password;

    public String login() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();

        try {
            request.login(username, password);
        } catch (ServletException e) {
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Login failed!", null));
            return "login";
        }

        //you can fetch user from database for authenticated principal and do some action  
        Principal principal = request.getUserPrincipal();
        log.info("Authenticated user: " + principal.getName());


        if (request.isUserInRole("Admin")) {
            return "/admins/admins?faces-redirect=true";
        } else {
            return "/users/users?faces-redirect=true";
        }
    }

    public String logout() {
        String result = "/index?faces-redirect=true";

        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();

        try {
            request.logout();
        } catch (ServletException e) {
            log.log(Level.SEVERE, "Failed to logout user!", e);
            result = "/loginError?faces-redirect=true";
        }

        return result;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

你能告诉我我做错了什么吗,因为我在尝试进行身份验证时总是收到“登录失败”错误 - 使用 admin/admin 作为用户名/密码。如果您需要任何其他详细信息,请告诉我 - 如果有人想看一下,我也可以提供该项目的档案。

提前谢谢你,很抱歉这么长的帖子。:)

4

1 回答 1

1

我们在使用 Glassfish v3 和 PostgreSQL 数据库的 Lubuntu 服务器上遇到了类似的问题。确保您已在 Glassfish 域中安装 PostgreSQL 驱动程序。

复制到:

\glassfish\domains\YOURDOMAIN\lib

一个 JDBC 4 驱动程序,你可以在这里找到:

http://jdbc.postgresql.org/download.html

必须帮助:)

于 2012-07-30T11:44:55.010 回答