2012-07-16 52 views
1

我正在轉換到GlassFish 3.1.2,似乎無法解決認證問題。JSF 2.0 +程序認證= 403 :)

議程很簡單:我想要一個登錄bean爲用戶進行編程認證。驗證似乎工作(代碼通過login()方法),但服務器最終顯示爲403受保護的資源...請幫助:)

這裏有更多的細節。沒有與名稱/密碼對純JSF的登錄頁面:

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

    <ui:define name="body"> 
     <h:form id="form"> 
      <p:messages /> 

      <p:panel> 
       <h:panelGrid> 
        <h:outputText value="User Name" /> 
        <p:inputText value="#{loginBean.userName}" id="userName" 
         required="true" /> 
        <p:message for="userName" /> 

        <h:outputText value="Password" /> 
        <p:password value="#{loginBean.password}" id="password" 
         required="true" /> 
        <p:message for="password" /> 

       </h:panelGrid> 

       <h:panelGrid columns="2"> 
        <p:commandButton value="Clear" 
         actionListener="#{loginBean.clear()}" ajax="false" /> 

        <p:commandButton value="Login" action="#{loginBean.login()}" 
         ajax="false" /> 
       </h:panelGrid> 
      </p:panel> 
     </h:form> 
    </ui:define> 
</ui:composition> 

和實行登錄

@Named("loginBean") 
@SessionScoped 
public class LoginBean implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Inject 
    @Named("dao") 
    private Dao dao; 

    private String userName; 

    private String password; 

    @Inject 
    private UserBean userBean; 

    ... 

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

     try { 
      request.login(getUserName(), getPassword()); 

      Principal principal = request.getUserPrincipal(); 

      logger.info("Logged in successfully: " + principal); 
     } catch (ServletException e) { 
      Messages.addError("Invalid user name or password."); 
      return null; 
     } 

     User user = dao.findSingle("SELECT u FROM User AS u WHERE u.name = ?1", 
       getUserName()); 

     if (user == null) { 
      logger.severe("Unable to find user record after successful authentication"); 

      Messages.addError("Unable to load user record"); 
      try { 
       request.logout(); 
      } catch (ServletException e) { 
       logger.log(Level.SEVERE, "Unable to logout after failed login attempt", e); 
      } 
      return null; 
     } 

     getUserBean().setUser(user); 

     return "/list/list.xhtml?faces-redirect=true"; 
    } 

    ... 

    accessors 

    ... 
} 

這裏一個bean是我的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"> 

    <display-name>GM</display-name> 

    <context-param> 
     <param-name>javax.faces.PROJECT_STAGE</param-name> 
     <param-value>Development</param-value> 
    </context-param> 

    <!-- Faces Servlet --> 
    <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>*.xhtml</url-pattern> 
    </servlet-mapping> 

    <login-config> 
     <realm-name>gmRealm</realm-name> 
    </login-config> 

    <security-role> 
     <role-name>user</role-name> 
    </security-role> 

    <security-role> 
     <role-name>admin</role-name> 
    </security-role> 

    <security-constraint> 
     <web-resource-collection> 
      <web-resource-name>Protected Area</web-resource-name> 
      <url-pattern>/list/*</url-pattern> 
     </web-resource-collection> 
     <auth-constraint> 
      <role-name>user</role-name> 
     </auth-constraint> 
    </security-constraint> 

    <security-constraint> 
     <web-resource-collection> 
      <web-resource-name>Admin Area</web-resource-name> 
      <url-pattern>/admin/*</url-pattern> 
     </web-resource-collection> 
     <auth-constraint> 
      <role-name>admin</role-name> 
     </auth-constraint> 
    </security-constraint> 

    <welcome-file-list> 
     <welcome-file>login.xhtml</welcome-file> 
    </welcome-file-list> 

</web-app> 

這裏是該項目的文件夾結構:

Folder structure

我也能夠成立的境界如這裏討論:http://blog.gamatam.com/2009/11/jdbc-realm-setup-with-glassfish-v3.html

沒什麼特別的,AFAICT。

但是,每當我到受保護的資源成功登錄後,我得到:

HTTP Status 403 - Access to the requested resource has been denied 

儘管服務器日誌中包含的信息的事實:

INFO: Logged in successfully: nick 

還要注意的是,當我從login()方法的返回值中刪除了「?faces-redirect = true」,初始受保護資源在登錄後立即呈現,但隨後的所有請求都以403失敗。

下面是它顯示了在調試器:

Debugging view

我也覺得我已經做了功課:

Performing user authentication in Java EE/JSF using j_security_check

Programmatically control login with Servlet 3.0

JSF 2.0 Simple login page

Glassfish 3 security - Form based authentication using a JDBC Realm

請幫忙...

+0

您是否嘗試過回 「列表/ list.xhtml?面臨重定向=真正的」(不帶 「/」)或 「list.xhtml?面臨重定向=真正的」(無 「/目錄」)?另外,請顯示您的文件夾結構以查看導航規則是否存在問題。 – 2012-07-16 05:34:43

+0

感謝您的建議。試了兩個,列表/ list.xhtml給出了相同的403和list.xhtml,給出「無法找到匹配的導航案件與從視圖ID'/login.xhtml'的行動'#{loginBean.login()}'結果爲'list.xhtml?faces-redirect = true'「 – 2012-07-16 11:19:09

+2

您的約束配置表明具有」admin「角色的用戶無法訪問」list「目錄。這是你想要的嗎?如果不是,則應將角色「管理員」添加到受保護區域約束。 – 2012-07-16 11:44:21

回答

0

哦,好吧,我想這個是太特別的部署。我最終在Tomcat堆棧中重新定義了Spring的原型。像現在的魅力:)。

-1

我想你不允許jsf春季安全資源。在http標籤的security.xml中添加以下行。

<http .........> 
    <intercept-url pattern="/javax.faces.resource/**" access="permitAll"/> 
</http>