2013-09-24 47 views
0

我在使用領域和request.login()方法登錄用戶時遇到了一些問題,我發現了一些類似的問題,但都沒有解決我的問題。Glassfish JDBCRealm和request.login()

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. 

回答

0

我覺得這裏的線索:WARNING: No Principals mapped to Role [ADMIN].

在web.xml文件中你有:

<auth-constraint> 
     <role-name>ADMIN</role-name> 
</auth-constraint> 

而且在Glassfish的-web.xml文件中你有:

<security-role-mapping> 
<role-name>ADMINS</role-name> 
<group-name>ADMINS</group-name> 

正如我undersand這種機制下,你必須將角色映射從web.xml到glassfish-web.xml中的組名稱。兩個文件中的角色名稱應該相同。還要檢查數據庫表中給定用戶的角色名是否正確。

這裏有一些資源:

https://netbeans.org/kb/docs/web/security-webapps.html https://netbeans.org/kb/docs/javaee/ecommerce/security.html

+0

上面提到的「錯字」固定和對角色的鬃毛是正確的數據庫,但仍然沒有成功。擺脫了「警告:無法將主體映射到角色[ADMIN]」。錯誤壽。 – Sergei