2014-02-06 88 views
1

我想限制用戶訪問任何頁面,如果用戶,如果沒有授權。我正在使用jsf 2.2和primefaces。下面是我的代碼:如何限制未經授權的用戶訪問頁面直接在jsf

我的過濾器

@WebFilter(filterName = "AuthFilter", urlPatterns = { "*.xhtml" }) 
public class AuthFilter implements Filter { 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
    } 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, 
      FilterChain chain) throws IOException, ServletException { 
     try { 


      HttpServletRequest request = (HttpServletRequest) req; 
      HttpServletResponse response = (HttpServletResponse) res; 
      HttpSession session = request.getSession(false); 

      String user = (session != null) ? session.getAttribute("username") 
        .toString() : null; 

      String loginURL = request.getContextPath() + "/ldapLogin.xhtml"; 
      boolean loginRequest = request.getRequestURI().startsWith(loginURL); 
      boolean resourceRequest = request.getRequestURI().startsWith(
        request.getContextPath() 
          + ResourceHandler.RESOURCE_IDENTIFIER); 
      if (user != null || loginRequest) 
       chain.doFilter(request, response); 
      } else { 
       response.sendRedirect(request.getContextPath() 
         + "/ldapLogin.xhtml"); 
      } 

     } catch (Throwable t) { 
      System.out.println(t.getMessage()); 
     } 
    } 

這裏我控制進入的其他條件時,我的會話沒有生效或者如果我試圖直接訪問一個頁面,但無法重定向到ldapLogin.xhtml

Web.xml中

<context-param> 
    <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name> 
    <param-value>ApplicationResources</param-value> 
    </context-param> 
    <context-param> 
    <param-name>javax.servlet.jsp.jstl.fmt.fallbackLocale</param-name> 
    <param-value>en</param-value> 
    </context-param> 
    <context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
      /WEB-INF/applicationContext-dao.xml, 
      /WEB-INF/springLdap-security.xml 
     </param-value> 
    </context-param> 
    <context-param> 
    <param-name>javax.faces.PROJECT_STAGE</param-name> 
    <param-value>Development</param-value> 
    </context-param> 
    <context-param> 
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name> 
    <param-value>client</param-value> 
    </context-param> 
    <context-param> 
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name> 
    <param-value>.xhtml</param-value> 
    </context-param> 
    <context-param> 
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name> 
    <param-value> 
      /WEB-INF/taglibs/acegijsf.taglib.xml 
     </param-value> 
    </context-param> 
    <context-param> 
    <param-name>primefaces.THEME</param-name> 
    <param-value>bootstrap</param-value> 
    </context-param> 
    <context-param> 
    <param-name>org.omnifaces.FACES_VIEWS_SCAN_PATHS</param-name> 
    <param-value>/*.xhtml</param-value> 
    </context-param> 
    <listener> 
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class> 
    </listener> 
    <listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 
    <servlet> 
    <servlet-name>faces</servlet-name> 
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
    <servlet-name>faces</servlet-name> 
    <url-pattern>*.xhtml</url-pattern> 
    </servlet-mapping> 

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

LoginLdap.java

public String ldapLoginAuthentcator() { 
     if (contact != null) { 
      HttpSession session = FilterUtil.getSession(); 
      session.setAttribute("username", user.getName()); 
      return "success"; 
     } else { 
FacesContext.getCurrentInstance().addMessage(null, 
    new FacesMessage(FacesMessage.SEVERITY_WARN,"Invalid Login!", "Please TryAgain!")); 
      return "login"; 
     } 

最後FilterUtil.java

public class FilterUtil { 

     public static HttpSession getSession() { 
    return(HttpSession)FacesContextgetCurrentInstance().getExternalContext().getSession(true); 
     } 

}

我不知道是什麼問題,但是當我試圖訪問一個頁面,即使我被授權或者我的會話沒有被驗證,但是我仍然可以訪問該頁面。任何幫助將被佔用。所有頁面當前都位於相同的根路徑中,而不是放置在web-inf文件夾中的公共目錄。

UPDATE:

當我試圖直接訪問一個頁面沒有有效的會話,例如,如果我試圖訪問http://192.35.36.178:8042/SOW/start和來參加我的篩選,成功地過濾,但重定向沒有發生,當我試圖檢查它與螢火蟲它重定向到一個不同的星球。其實際重定向到

"http:172.36.98.658//8042/SOW/javax.faces.resource/theme.css.xhtml?ln=primefaces-bootstrap" 

與狀態302實測值代替redrecting到 response.sendRedirect是(request.getContextPath()+ 「/ldapLogin.xhtml」) 以及當我試圖檢查contextPath其顯示/母豬

+0

@Makky感謝您快速響應,實際上我是jsf中的新手,我曾經在struts2上工作,但是對於項目需求我們需要實現這個安全性。然而,我不想轉移到PhaseListener,我也想知道這個過濾器有什麼問題,以及爲什麼當用戶不是有效的用戶時,它不會被重定向到login.xhtml?以及如果你有一些PhaseListener的工作代碼,那麼我想試一試。 –

+0

好的...你的意思是這個過濾器不會爲阿賈克斯調用正確,然後請分享我一些工作代碼.. thanx提前 –

+0

你可以確認重定向請求(302)實際上是回到瀏覽器,正在請求適當的URL? – kolossus

回答

0

我會告訴你我怎麼做,而不使用Filter或PhaseListener。

最好的方式,如果你使用的模板,然後把此行中模板的身體,或者(如果沒有模板)在每一個頁面要限制訪問:

<f:event type="preRenderView" listener="#{yourBean.checkPermissions}"/> 

在模板:

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:ui="http://java.sun.com/jsf/facelets" 
     > 
<h:head> 
    <meta charset="UTF-8" /> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> 
    <h:outputStylesheet name="stylesheet.css"/>  
    <title>${pageTitle}</title> 
    <meta http-equiv="keywords" content="${metaKeywords}" /> 
    <meta http-equiv="description" content="${metaDescription}" /> 
</h:head> 

<body> 
<f:event type="preRenderView" listener="#{yourBean.checkPermissions}"/> 
... 
在Bean中

添加監聽方法是這樣的:

public void checkPermissions(ComponentSystemEvent event) { 

     FacesContext fc = FacesContext.getCurrentInstance(); 
     HttpSession httpSession = (HttpSession)(fc.getExternalContext().getSession(false)); 
     String cid = (String) httpSession.getAttribute(AttributeName.ADMINISTRATOR_CLIENT_LOGIN_ID); 
     if(cid == null){ 
      ConfigurableNavigationHandler handler = (ConfigurableNavigationHandler)fc.getApplication().getNavigationHandler(); 
      handler.performNavigation(this.navi.getClientLogin().getLink()); 
      return; 
     } 
     .... 
     .... 
    } 

更新:使用過濾器的一個工作示例(我測試了它使用JSF2.2 Mojarra 2。2,Tomcat的7):在您的的web.xml

編輯/添加/本:

.... 
    <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> 


.... 

,這裏是一個樣品過濾器默認地將Impl:

import java.io.IOException; 

import javax.faces.application.ResourceHandler; 
import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.FilterConfig; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.annotation.WebFilter; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import javax.servlet.http.HttpSession; 

@WebFilter(filterName = "AuthFilter", urlPatterns = { "*.xhtml" }) 
public class AuthFilter implements Filter { 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
    } 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, 
      FilterChain chain) throws IOException, ServletException { 
     try { 
      System.out.println("doFilter ..."); 
      HttpServletRequest request = (HttpServletRequest) req; 
      HttpServletResponse response = (HttpServletResponse) res; 
      HttpSession session = request.getSession(false); 
      String user = (session != null) ? (String)session.getAttribute("username") : null; 
      String loginURL = request.getContextPath() + "/ldapLogin.xhtml"; 
      boolean loginRequest = request.getRequestURI().startsWith(loginURL); 
      boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath()+ ResourceHandler.RESOURCE_IDENTIFIER); 
      if (user != null || loginRequest) { 
       chain.doFilter(request, response); 
      } else { 
       response.sendRedirect(request.getContextPath() + "/ldapLogin.xhtml"); 
      } 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    @Override 
    public void destroy() { 
     //  
    } 
} 
+0

''在JSF2.2中更可取 – kolossus

+1

雖然這可能有效,但這不是推薦的方法。過濾器是。它能夠覆蓋非JSF請求。 – BalusC

+0

@kolossus,謝謝,這正是你的建議,正如我從一箇舊項目中複製它,我關注的不是細節上的想法。 –

相關問題