这几天闲着没事,开始研究起项目过滤器的使用,感觉没啥意思。蛮记录下,也当作是学习笔记了!!!
一、 中文编码过滤器
<filter>
<description>编码过滤器</description>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- 中文编码过滤映射 -->
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
二、 静态资源过滤器
<filter>
<description>处理静态资源的过滤器</description>
<filter-name>resourceFilter</filter-name>
<filter-class>ffcs.cn.common.resourceFilter.ResourceHttpRequestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>resourceFilter</filter-name>
<url-pattern>/resource/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>resourceFilter</filter-name>
<url-pattern>/upload/*</url-pattern>
</filter-mapping>
ResourceHttpRequestFilter类
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.support.ServletContextResource;
/**
* 处理静态资源的过滤器
* 用于解决Spring MVC在处理静态资源(js,css等)的时候也会被拦截器过滤的问题
*
* @author mengyang
*
*/
public class ResourceHttpRequestFilter implements Filter {
private final Logger logger = Logger.getLogger(getClass());
public static final String METHOD_HEAD = "HEAD";
public void destroy() {
}
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)arg0;
HttpServletResponse response = (HttpServletResponse)arg1;
Resource resource = getResource(request);
if (resource == null) {
logger.debug("No matching resource found - returning 404");
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// check the resource's media type
MediaType mediaType = getMediaType(request, resource);
if (mediaType != null) {
if (logger.isDebugEnabled()) {
logger.debug("Determined media type [" + mediaType + "] for " + resource);
}
}
else {
if (logger.isDebugEnabled()) {
logger.debug("No media type found for " + resource + " - returning 404");
}
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// header phase
if (new ServletWebRequest(request, response).checkNotModified(resource.lastModified())) {
logger.debug("Resource not modified - returning 304");
return;
}
setHeaders(response, resource, mediaType);
// content phase
if (METHOD_HEAD.equals(request.getMethod())) {
logger.trace("HEAD request - skipping content");
return;
}
writeContent(response, resource);
}
public void init(FilterConfig arg0) throws ServletException {
}
//获取请求的静态资源
protected Resource getResource(HttpServletRequest request) throws UnsupportedEncodingException {
String URI = URLDecoder.decode(request.getRequestURI(), "utf-8");
String context = request.getContextPath();
String path = URI.substring(URI.indexOf(context) + context.length());
Resource resource = new ServletContextResource(request.getSession().getServletContext(), path);
if (resource.exists() && resource.isReadable()) {
if (logger.isDebugEnabled()) {
logger.debug("Found matching resource: " + resource);
}
return resource;
}
else if (logger.isTraceEnabled()) {
logger.trace("Relative resource doesn't exist or isn't readable: " + resource);
}
return null;
}
//获取资源的MediaType
protected MediaType getMediaType(HttpServletRequest request, Resource resource) {
String mimeType = request.getSession().getServletContext().getMimeType(resource.getFilename());
return (StringUtils.hasText(mimeType) ? MediaType.parseMediaType(mimeType) : null);
}
//设置响应头部
protected void setHeaders(HttpServletResponse response, Resource resource, MediaType mediaType) throws IOException {
long length = resource.contentLength();
if (length > Integer.MAX_VALUE) {
throw new IOException("Resource content too long (beyond Integer.MAX_VALUE): " + resource);
}
response.setContentLength((int) length);
response.setContentType(mediaType.toString());
}
//直接把资源流写到响应中
protected void writeContent(HttpServletResponse response, Resource resource) throws IOException {
FileCopyUtils.copy(resource.getInputStream(), response.getOutputStream());
}
}
也可以在application配置静态资源过滤器
<!-- 静态资源 -->
<mvc:annotation-driven></mvc:annotation-driven>
<mvc:resources location="/resource/" mapping="/resource/**"
cache-period="864000" />
三、 登录验证过滤器
该过滤器主要原理就是根据是否存在session信息判断是否处于登录状态,不是就返回登录页
<!-- ************************登录验证过滤 **************************-->
<filter>
<description>登录验证</description>
<filter-name>loginFilter</filter-name>
<filter-class>ffcs.cn.common.loginFilter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/peam/*</url-pattern>
</filter-mapping>
LoginFilter类
import java.io.IOException;
import java.io.PrintWriter;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ffcs.cn.common.Constants;
/**
* 验证用户登录
* @author zhangy
*
*/
public class LoginFilter implements Filter{
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//查询session是否有用户信息
Object user = request.getSession().getAttribute(Constants.LOGIN_USER_SESSION);
if(user!=null){
chain.doFilter(request, response);
}else {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
String loginPage = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/MySsh";
StringBuilder builder = new StringBuilder();
builder.append("<script type=\"text/javascript\">");
builder.append("alert('网页过期,请重新登录!');");
builder.append("window.top.location.href='");
builder.append(loginPage);
builder.append("';");
builder.append("</script>");
out.print(builder.toString());
}
}
@Override
public void destroy() {
}
}
四、 验证码过滤器
原理和登录验证过滤器一样,也是检查session信息
<!-- ************************验证码过滤 **************************-->
<filter>
<description>验证码</description>
<filter-name>verificationCodeFilter</filter-name>
<filter-class>ffcs.cn.common.VerificationCodeFilter.VerificationCodeFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>verificationCodeFilter</filter-name>
<url-pattern>/yzm_check</url-pattern>
</filter-mapping>
VerificationCodeFilter类
import java.io.IOException;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 验证码判断
* @author
*
*/
public class VerificationCodeFilter implements Filter{
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String checkcode =request.getParameter("t_checkcode");
String rightCode = (String)request.getSession().getAttribute("rand");
if(checkcode!=null && ("9999".equals(checkcode)||checkcode.equals(rightCode))){
//验证码正确
filterChain.doFilter(request, response);
}else{
//验证码错误
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write("{\"message\":\"验证码错误\",\"data\":null,\"success\":false}");
}
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
五、防sql注入过滤
<!-- ************************防sql注入过滤 **************************-->
<filter>
<filter-name>XssFilter</filter-name>
<filter-class>ffcs.cn.common.xssFilter.XssFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XssFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
XssFilter类
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.codehaus.jackson.map.ObjectMapper;
public class XssFilter implements Filter {
FilterConfig filterConfig;
private ArrayList<String> filterURL = new ArrayList<String>();
private ArrayList<String> excludedFilterURL = new ArrayList<String>();
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
String url = Globals.getGlobalProperty("filter.xss.url");
System.out.println("------------conf xss sql filter------------"+url);
String[] urlArr = url.split(";");
for (String str:urlArr)
{
filterURL.add(str.trim());
}
//设置不过滤的url @Author linph
String excludedUrl = Globals.getGlobalProperty("filter.excluded.url");
String[] excludedUrlArr = excludedUrl.split(";");
for (String str:excludedUrlArr) {
excludedFilterURL.add(str.trim());
}
}
public void destroy() {
this.filterConfig = null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
request.setCharacterEncoding("utf-8");
String url = req.getRequestURI();
boolean isSpecialUrl = false;
//是否跳过过滤
boolean isExcluded = false;
if (filterURL.contains(url)) {
isSpecialUrl = true;
}
if (excludedFilterURL.contains(url)) {
isExcluded = true;
}
if (!isExcluded) {
Map map = request.getParameterMap();
Set keySet = map.keySet();
for (Object object : keySet) {
String paraName = object.toString();
if (isSpecialUrl && "flowXml".equals(paraName)) {
continue;
}
String[] values = request.getParameterValues(paraName);
if (values != null && isSpecialUrl && "newTxt".equals(paraName)) {
continue;
} else {
for (int i = 0; i < values.length; i++) {
String val = values[i];
try{
val = java.net.URLDecoder.decode(val, "UTF-8");
}catch(Exception e){
e.printStackTrace();
}
if(sqlValidator(val) || scriptValidator(val)){
//String path = req.getContextPath();
//String basePath = req.getScheme()+"://"+req.getServerName()+":"+req.getServerPort()+path;
if (isAjaxRequest(req)) {
ObjectMapper mapper = new ObjectMapper();
resp.setContentType("application/json;charset=utf-8");
resp.setCharacterEncoding("UTF-8");
resp.setHeader("Cache-Control", "no-cache");
resp.getWriter().write(mapper.writeValueAsString("错误"));
resp.getWriter().flush();
resp.getWriter().close();
return;
} else {
//req.getRequestDispatcher("/WEB-INF/views/common/err.jsp").forward(request, response);
values[i] = cleanXSS(val);
}
}
}
}
}
}
filterChain.doFilter(request, response);
}
public static boolean isAjaxRequest(HttpServletRequest request) {
String requestType = request.getHeader("X-Requested-With");
return requestType != null && requestType.equals("XMLHttpRequest");
}
private boolean sqlValidator(String fieldValue){
//禁止OR、联合执行语句方式注入
String parStr = "\\w*((%27)|(\\')\\s*)(((%6F)|o|(%4F))((%72)|r|(%52))|(union))";
Pattern pattern = Pattern.compile(parStr, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(fieldValue);
if(matcher.find())
return true;
//禁止以大于、小于、等于、注释的方式绕过原语句,注入SQL
parStr = "((%3C)|(<)|(0x3C)|(%3D)|(=)|(0x3D)|(%3E)|(>)|(0x3E))[^\\n]*((%27)|(\\')|(0x27)|(%3B)|(:)|(0x3B))";
pattern = Pattern.compile(parStr, Pattern.COMMENTS|Pattern.CASE_INSENSITIVE);
matcher = pattern.matcher(fieldValue);
if(matcher.find())
return true;
//禁止有危害SQL关键字和利用引号分号非法结束原语句,注入SQL//(and)|(exec)|(insert)|(select)|(delete)|(update)|(count)|(*)|(%)|(chr)|(mid)|(master)|(truncate)|(char)|(declare)
//parStr = "(union)|(select)|(concat)|(drop)|(truncate)|(delete)|(((\\';)+|(\\-\\-)+).*)|(0x7c)|(\\|)|(%7C)|(0x60)|(`)|(%60)";
parStr = "(?:')|(?:([a-z0-9A-Z_\\s\\(\\)]+\\-\\-))|(/\\*(?:.|[\\n\\r])*?\\*/)|(\\';)|(0x7c)|(\\|)|(`)|"
+ "(\\b(select|and|or|update|delete|insert|trancate|char|into|substr|mid|\\*|ascii|declare|exec|count|master|into|drop|execute)[\\s+\\(\\)]\\b)";
pattern = Pattern.compile(parStr, Pattern.COMMENTS|Pattern.CASE_INSENSITIVE);
matcher = pattern.matcher(fieldValue);
if(matcher.find())
return true;
return false;
}
private boolean scriptValidator(String fieldValue){
//禁止HTML及SCRIPT标签
String parStr = "((%3C)|<)\\s*((%2F)|\\/)*\\s*[A-Za-z0-9%]+\\s*((%3E)|>)";
Pattern pattern = Pattern.compile(parStr, Pattern.COMMENTS|Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(fieldValue);
if(matcher.find()||fieldValue.toLowerCase().indexOf("script")>=0)
return true;
//判断IMG及SRC注入方式
parStr = "(((%3C)|<)\\s*((%69)|i|(%49))((%6D)|m|(%4D))((%67)|g|(%47))[^\\n]+((%3E)|>))|(((%53)|s|(%73))((%72)|r|(%52))((%43)|c|(%63)))";
pattern = Pattern.compile(parStr, Pattern.COMMENTS|Pattern.CASE_INSENSITIVE);
matcher = pattern.matcher(fieldValue);
if(matcher.find())
return true;
//判断常用HTML事件函数及转义字符攻击方式
parStr = "\\b(fromCharCode|onmouse|onclick|ondblclick|onload|onblur|onFocus|onkeydown|onkeypress|onkeyup|"|&apos|&|<|>|(&\\#[0-9a-fA-F]+)|'|\"|`)";
pattern = Pattern.compile(parStr, Pattern.COMMENTS|Pattern.CASE_INSENSITIVE);
matcher = pattern.matcher(fieldValue);
if(matcher.find())
return true;
//禁止访问WEB-INF、XML、UNICODE
parStr = "(WEB\\-INF)|(xml)|((\\\\)(u)[0-9a-fA-F]{2,5})";
pattern = Pattern.compile(parStr, Pattern.COMMENTS|Pattern.CASE_INSENSITIVE);
matcher = pattern.matcher(fieldValue);
if(matcher.find())
return true;
return false;
}
private String cleanXSS(String value) {
value = value.replaceAll("<", "<").replaceAll(">", ">");
value = value.replaceAll("\\(", "(").replaceAll("\\)", ")");
value = value.replaceAll("'", "'");
value = value.replaceAll("eval\\((.*)\\)", "");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']","\"\"");
value = value.replaceAll("(?i)script", "");
//value = value.replaceAll("script", "");
return value;
}
}
import java.io.InputStream;
import java.util.Properties;
public class Globals {
private static Properties initProps = null;
public static String getGlobalProperty(String name) {
loadProperties();
if(initProps.getProperty(name) != null && !initProps.getProperty(name).equals(""))
return initProps.getProperty(name);
else
return "";
}
public static boolean getBooleanGlobalProperty(String name) {
loadProperties();
if(initProps.getProperty(name) != null && !initProps.getProperty(name).equals("")) {
if(initProps.getProperty(name).equals("true"))
return true;
else return false;
}
else return false;
}
public static int getIntGlobalProperty(String name) {
String prop = getGlobalProperty(name);
return Integer.parseInt(prop);
}
private synchronized static void loadProperties() {
if (initProps == null) {
initProps = new Properties();
InputStream in = null;
try {
in = Globals.class.getResourceAsStream("/global.properties");
initProps.load(in);
} catch (Exception e) {
System.err.println("Load global.properties configure file error!");
} finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e) {
}
}
}
}
}```
版权声明:本文为weixin_40496191原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。