我正在嘗試將驗證添加到基於JSF 2的應用程序。我開始遵循this教程。無法在JSF 2 + Glassfish 3上使用JDBC Realm登錄
下面是我的數據庫導出:
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」 和密碼 「管理員」(與SHA-256和十六進制編碼加密)一個用戶。
我在我的Glassfish管理控制檯中創建了一個JDBC連接池,它正在成功地ping數據庫。我已將此池分配給名爲「jdbc/observer」的JDBC資源。之後,在配置 - >服務器配置 - >安全 - >三界我創建 「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 "https://stackoverflow.com/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輸入用戶名/密碼。請告訴我,如果你需要任何其他細節 - 如果有人想看看,我還可以提供該項目的檔案。
預先感謝您,並對長期發帖感到抱歉。 :)
謝謝你的建議,並對遲到的迴應感到抱歉。我使用的是MySQL而不是PostgreSQL,所以我會嘗試遷移數據庫,並在有幫助的情況下提供反饋。 :) – 2012-08-04 11:05:33
我猜對於mysql有一個類似的驅動程序來下載:) – Atais 2012-08-08 14:09:46