レルムと request.login() を使用してユーザーをログインさせる際に問題が発生しています。同様の質問がいくつか見つかりましたが、問題を解決するものはありません。
ログイン.xhtml
<h:form>
<h:outputLabel for="usernameInput">
#{bundle['login.email']}:
</h:outputLabel>
<h:inputText id="usernameInput" value="#{loginBean.email}"
required="true" />
<br />
<h:outputLabel for="passwordInput">
#{bundle['login.password']}:
</h:outputLabel>
<h:inputSecret id="passwordInput" value="#{loginBean.password}"
required="true" />
<br />
<h:commandButton value="${bundle['login.submit']}"
action="#{loginBean.login}" />
</h:form>
loginBean.java
@Stateless
@Named
public class LoginBean {
@EJB
private UserFacadeREST ejbRef;
private String email;
private String password;
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public String login() {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest)
context.getExternalContext().getRequest();
User user = getUser(this.email);
if (user != null) {
hashPassword();
context.addMessage(null, new FacesMessage(this.email));
context.addMessage(null, new FacesMessage(this.password));
context.addMessage(null, new FacesMessage(user.getEmail()));
context.addMessage(null, new FacesMessage(user.getPassword()));
if (user.getPassword().equals(this.password)) {
try {
request.login(this.email, this.password);
} catch (ServletException e) {
context.addMessage(null, new FacesMessage("Login failed."));
return "error";
}
return "admin/index";
} else {
context.addMessage(null, new FacesMessage("Incorrect password"));
}
} else {
context.addMessage(null, new FacesMessage("There is no account "
+ "with that email"));
}
return "error";
}
public void logout() {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest)
context.getExternalContext().getRequest();
try {
request.logout();
} catch (ServletException e) {
context.addMessage(null, new FacesMessage("Logout failed."));
}
}
private User getUser(String email) {
try {
User user = (User) getEntityManager().
createNamedQuery("User.findByEmail").
setParameter("email", email).
getSingleResult();
return user;
} catch (NoResultException e) {
System.err.println("NoResultException" + e.getMessage());
return null;
}
}
public EntityManager getEntityManager() {
return ejbRef.getEntityManager();
}
/*
* md5 password.
*/
public void hashPassword(){
try {
byte[] hash = this.password.getBytes();
MessageDigest md = MessageDigest.getInstance("md5");
hash = md.digest(hash);
StringBuilder hexString = new StringBuilder();
for (int i = 0; i < hash.length; i++) {
if ((0xff & hash[i]) < 0x10) {
hexString.append("0").append(Integer.toHexString((0xFF & hash[i])));
} else {
hexString.append(Integer.toHexString(0xFF & hash[i]));
}
}
String md5Password = hexString.toString();
setPassword(md5Password);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(UserController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.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>
<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>/Login.xhtml</form-error-page>
</form-login-config>
</login-config>
<security-constraint>
<web-resource-collection>
<web-resource-name>Secure Pages</web-resource-name>
<description/>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
</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="">
<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>
<security-role-mapping>
<role-name>USERS</role-name>
<group-name>USERS</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>ADMINS</role-name>
<group-name>ADMINS</group-name>
<principal-name>berry</principal-name>
</security-role-mapping>
</glassfish-web-app>
レルムのセットアップ:
Realm Name : JDBCRealm
Class Name : com.sun.enterprise.security.ee.auth.realm.jdbc.JDBCRealm
JAAS Context:jdbcRealm
JNDI: mysql/blueberrysoup
User Table: user
User Name Column: email
Password Column: password
Group Table: groups
Group Name Column: role_name
Password Encryption Algorithm: MD5
Digest Algorithm: MD5
Charset: UTF-8
最後に、glassfish によってスローされる例外:
WARNING: No Principals mapped to Role [ADMIN].
INFO: Loading application [blueberrysoup] at [/blueberrysoup]
INFO: blueberrysoup was successfully deployed in 3,944 milliseconds.
WARNING: WEB9102: Web Login Failed: com.sun.enterprise.security.auth.login.common.LoginException: Login failed: Security Exception
WARNING: JSF1064: Unable to find or serve resource, /user/error.xhtml.