我试图限制用户访问任何页面,如果用户未经授权。我正在使用jsf 2.2和primefaces。以下是我的代码:
我的过滤器
@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时,我的控件进入了else条件
网嗯
<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>
login LDAP.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文件夹中的公共文件位于同一根路径中。
更新:
当我尝试在没有有效会话的情况下直接访问页面时,例如,如果我尝试访问http://192.35.36.178:8042/SOW/start
并且它进入我的过滤并成功过滤但重定向没有发生,当我尝试使用firebug检查它时重定向到一些不同的行星。它实际上重定向到
"http:172.36.98.658//8042/SOW/javax.faces.resource/theme.css.xhtml?ln=primefaces-bootstrap"
状态302找到而不是redrecting到response.sendRedirect(request.getContextPath()+“/ oldapLogin.xhtml”)以及当我试图检查contextPath它的显示/播种
我将告诉你如何在不使用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;
}
....
....
}
更新:使用Filter的一个工作示例(我测试了它使用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() {
//
}
}