一 Filter概述
Filter 技术是servlet 2.3 新增加的功能,它新增加的功能包括:
1. 应用程序生命周期事件控制
2. 新的国际化
3. 澄清了类的装载规则;
4. 新的错误及安全属性;
5. 不赞成使用HttpUtils 类
6. 各种有用的方法
7. 阐明并扩展了几个servlet DTD
8. filter功能
其中最重要的就是filter功能。它使用户可以改变一个request和修改一个response,
Filter 不是一个servlet,它不能产生一个response它能够在一个request到达servlet之前
预处理request,也可以在离开servlet时处理response。换种说法,filter其实是一个
“servlet chaining”(servlet 链)。
一个filter 包括:
1. 在servlet被调用之前截获
2. 在servlet被调用之前检查servlet request
3. 根据需要修改request头和request数据
4. 根据需要修改response头和response数据
5. 在servlet被调用之后截获
二 Filter在检修ABC系统中的应用
检修ABC系统在初期搭建框架的时候决定使用Filter来处理用户非法访问URL以及Session过期等问题。
我们首先定义了一些可以通过URL直接访问的页面,如登陆页面,重登陆页面等。当用户没有登陆而
尝试访问受保护的URL时,Filter将拦截该请求,并把访问的URL重定向到登陆页面。
在web.xml中的配置如下:
<filter>
<filter-name>filterservlet</filter-name>
<filter-class>com.comtop.app.common.FilterServlet</filter-class>
<init-param>
<param-name>freePages</param-name>
<param-value>
/Login.jsp;/LoginAction.do;/index.jsp;/ReLogin.jsp;/SSOLoginAction.do;
</param-value>
</init-param>
<init-param>
<param-name>toPage</param-name>
<param-value>/ReLogin.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>filterservlet</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>filterservlet</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
在<filter></filter>中定义一些基本信息,比如filter的名称,filter的类以及相关初始参数。这里我
们把能直接访问的页面定义为freePages,并定义了它的值。还定义了默认的重定向页面,Relogin.jsp。
接着定义了filter-mapping,让后缀名为.do或.jsp的URL都被Filter所保护。
FilterServlet具体代码(import部分省略):
public class FilterServlet extends HttpServlet implements Filter {
private FilterConfig filterConfig;
private String[] freePages;
private String toPage = null;
private static Logger logger;
/**
* 初始化filter(这里重写父类的方法)
* @param filterConfig FilterConfig filter配置对象
* @throws ServletException
*/
public void init(FilterConfig filterConfig) throws ServletException {
logger = Toolkit.getInstance().getLogger(this.getClass().getName());
int i = 0;
String pages = null;
StringTokenizer strTokenizer = null;
if(logger.isDebugEnabled()) {
logger.debug("init validate session filter ");
}
this.filterConfig = filterConfig;
//以下从配置文件获取配置信息
this.toPage = filterConfig.getInitParameter("toPage");
pages = filterConfig.getInitParameter("freePages");
if(toPage == null || pages == null || toPage.trim().length() == 0 ||
pages.trim().length() == 0) {
logger.error("web.xml中filterServlet没有配置初始化参数\"toPage\"或\"freePage\".");
throw new ServletException("web.xml中filterServlet没有配置初始化参数
\"toPage\"或\"freePage\".");
}
if(logger.isDebugEnabled()) {
logger.debug("toPage:" + toPage);
logger.debug("freePages:" + pages);
}
strTokenizer = new StringTokenizer(pages, ";");
this.freePages = new String[strTokenizer.countTokens()];
while(strTokenizer.hasMoreTokens()) {
freePages[i++] = strTokenizer.nextToken();
}
if(!isFreePage(toPage)) {
logger.error("web.xml中filter初始化参数\"toPage\"的值必须是\"freePage\"中的某个页面.");
throw new ServletException("web.xml中filter初始化参数\"toPage\"的值
必须是\"freePage\"中的某个页面.");
}
}
/**
* 判断一个请求URI是否是不过滤的页面
* @param requestURI String 请求URI
* @return boolean 返回true为不过滤页面
*/
private boolean isFreePage(String requestURI) {
boolean isFree = false;
for(int i = 0; i < freePages.length; i++) {
if(requestURI.endsWith(freePages[i])) {
return true;
}
}
return isFree;
}
/**
* 判断请求是否为有效Session
* @param request ServletRequest 请求对象
* @return boolean 返回true为有效Session
*/
private boolean isValidSession(ServletRequest request) {
HttpServletRequest httpRequest = (HttpServletRequest)request;
if(httpRequest.getSession().getAttribute(GlobalConstants.SECURITY_LOGIN_KEY)
==
GlobalConstants.SECURITY_IS_LOGIN) {
return true;
}
if(logger.isDebugEnabled()) {
logger.debug("Session无效,请求:" + httpRequest.getRequestURI());
}
return false;
}
/**
* 过滤动作
* @param request ServletRequest 请求对象
* @param response ServletResponse 响应对象
* @param filterChain FilterChain 过滤器链对象
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain
filterChain) {
String requestURI = null;
ActionErrors errors = new ActionErrors();
ActionError errorSession = null;
HttpServletRequest httpRequest = (HttpServletRequest)request;
HttpServletResponse httpResponse = (HttpServletResponse)response;
requestURI = httpRequest.getRequestURI();
if(logger.isDebugEnabled()) {
logger.debug("Session filter RequestURI:" + requestURI);
}
if(!isFreePage(requestURI)) { //如果是保护页面
if(!isValidSession(request)) { //如果Session无效
String toPageURL = null;
try {
toPageURL = httpRequest.getContextPath() + toPage;
httpResponse.encodeRedirectURL(toPageURL);
httpResponse.sendRedirect(toPageURL); //转发响应
} catch(IOException ex) {
logger.error("Session filter过滤时发生IO异常", ex);
}
}
}
if(!httpResponse.isCommitted()) { //如果响应未提交,交给过滤器链
try {
filterChain.doFilter(request, response);
} catch(ServletException sx) {
filterConfig.getServletContext().log(sx.getMessage());
} catch(IOException iox) {
filterConfig.getServletContext().log(iox.getMessage());
}
}
}
//父类的方法
public void destroy() {
}
public FilterConfig getFilterConfig() {
return this.filterConfig;
}
public void setFilterConfig(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
}
这里isFreePage方法判断用户访问的URL是否是受保护的,从配置文件中将freePages的值得到后,以分号
为隔离符将它们取出放到一个数组中,这个数组存放的每个String都是一个freePage。另外,isValidSession
方法判断在session中是否存在用户的登陆信息,如果用户未登陆,则返回false。每一个filter从doFilter()方法
中得到当前的request及response,在doFilter()方法中,以下代码完成核心判断:
if(!isFreePage(requestURI)) { //如果是保护页面
if(!isValidSession(request)) { //如果Session无效
String toPageURL = null;
try {
toPageURL = httpRequest.getContextPath() + toPage;
httpResponse.encodeRedirectURL(toPageURL);
httpResponse.sendRedirect(toPageURL); //转发响应
} catch(IOException ex) {
logger.error("Session filter过滤时发生IO异常", ex);
}
}
}
只有是通过isFreePage(requestURI)和isValidSession(request)两层验证的页面才能被访问到,基本实
现了防止用户非法访问页面的情况。在实际项目中还可以添加更多的验证方法。
分享到:
相关推荐
XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。比如这些代码包括HTML代码和客户端脚本。攻击者利用XSS漏洞旁路掉访问控制——例如同源策略(same origin...
通常,我们会设置登录检查机制,防止非登录用户访问某些特定资源。Filter可以在此过程中发挥关键作用,通过检查请求中的用户信息来判断是否允许访问。如果用户未登录,Filter可以直接返回错误页面或者重定向到登录...
这个名为"Struts2编写的通用(拦截器,过滤器)Filter"的项目,主要目标是防止用户非法访问未授权的页面,确保只有登录用户才能访问特定的资源。 **拦截器(Interceptor)** 拦截器是Struts2框架的核心特性之一,它...
- **数据校验**:检查请求参数的有效性,防止非法输入。 - **安全控制**:限制对某些资源的访问,比如实现登录检查。 - **字符编码转换**:确保请求和响应的编码一致,避免乱码问题。 - **性能优化**:如GZIP...
1. 输入验证与编码:对用户提交的数据进行严格的验证,拒绝非法字符和格式。同时,对输出的数据进行编码,例如使用HTML实体编码,避免恶意脚本被执行。 2. 使用HTTP头部的Content-Security-Policy:设置CSP可以限制...
本文将详细讲解如何利用监听器进行访问计数以及通过过滤器来过滤非法字符,以确保系统的安全性和用户体验。 首先,我们来看监听器。在Java的Servlet规范中,监听器是一种特殊的Servlet组件,它能够监听特定的事件并...
以下是一个简单的JSP页面,展示了如何使用JSP创建Filter内存马。虽然实际操作中可能涉及到更复杂的反射和安全绕过,但这个例子能说明基本思路: ```jsp ; charset=UTF-8" pageEncoding="UTF-8"%> ...
通过检查请求参数或会话状态,可以防止未授权用户访问受保护的资源。 2. **字符编码转换**:确保请求参数的正确编码,防止跨站脚本攻击(XSS)和其他编码相关的安全问题。 3. **性能优化**:例如,缓存静态资源,...
例如,对于管理员页面,只有登录且角色为管理员的用户才能访问。在`doFilter`方法中,我们可以检查`HttpServletRequest`的会话信息,判断用户是否有足够的权限,若无权限则重定向到登录页面或其他提示页面。 4. **...
为了防止其他程序修改主页设置,可以使用`RegistryChangeNotify`函数(Windows API),但C#中没有直接封装此API,我们需要使用P/Invoke(平台调用)技术。首先定义API声明: ```csharp [DllImport("advapi32.dll", ...
- **从安全角度**:统一的身份认证机制能够有效防止非法访问,保护系统安全。 - **从开发和维护角度**:减少了重复开发的工作量,简化了系统的维护流程。 综上所述,北京大学信息平台下的统一用户管理和身份认证...
5. **权限控制**:通过Filter实现不同角色对系统的访问权限限制,保护敏感信息不被非法访问。 6. **异常处理**:为防止程序运行时出现错误,需要设置全局异常处理,保证系统稳定运行。 项目中的"Graduation Design...
"防盗链filter"是一种常见的Java技术,用于防止网站的资源(如图片、视频、音频等)被其他未经授权的网站非法引用,即“盗链”。本篇文章将深入探讨Java防盗链filter的工作原理、实现方式以及其在实际应用中的重要性...
非法登录验证机制是其中的一种关键措施,用于检测并阻止非授权用户的访问尝试。 #### 实现方式 一种常见的实现非法登录验证的方法是在Web应用中设置过滤器(Filter)。通过配置特定的过滤器,可以在请求到达目标...
通过合理的权限设计,可以有效地保护系统资源,防止非法访问。 综上所述,Java Web开发中的用户权限管理是一个涵盖认证、授权、角色分配和安全框架等多个方面的复杂主题。掌握这些知识对于构建安全、可靠的Web应用...
资源保护过滤器的主要任务是保护敏感的Web资源免受非法访问和攻击。它可以实现如IP黑名单、速率限制、XSS和SQL注入防护等功能。例如,过滤器可以检查请求参数,防止恶意的脚本注入;或者根据预定义的规则限制同一IP...
接着是“防盗链(Anti-leech)”技术,这是一个防止网站资源被其他网站非法引用的重要机制。防盗链过滤器通常检查HTTP请求的来源(Referer头),如果发现请求并非来自预期的站点,就会阻止资源的访问,从而保护了...
设置合理的权限控制,避免非法用户访问敏感信息;对输入数据进行校验,防止SQL注入等攻击。 总的来说,基于SpringBoot+JavaWeb技术的在线考试系统是一个综合性的项目,涵盖了计算机专业的多个重要知识点,包括但不...
本文将详细介绍如何使用过滤器(Filter)在JSP中有效地防止XSS攻击。 首先,我们需要了解XSS攻击的基本原理。当用户在Web表单中输入数据,这些数据未经适当的验证和编码直接显示在页面上时,攻击者可以通过注入恶意...