java 屏蔽地域性访问_javaweb利用filter拦截未授权请求

项目上有个小需求,要限制访问者的IP,屏蔽未授权的请求。该场景使用过滤器来做再合适不过了。

SecurityFilter.java:

public class SecurityFilter implementsFilter {private Log log = LogFactory.getLog(SecurityFilter.class);private List whitelist = new ArrayList();private List regexlist = new ArrayList();private static final String _JSON_CONTENT = "application/json; charset=UTF-8";private static final String _HTML_CONTENT = "text/html; charset=UTF-8";private static final String _403_JSON = "{'code': '403', 'msg': '访问被拒绝,客户端未授权!'}";private static final String _403_HTML = "

403 Forbidden!


@lichmama
";

@Overridepublic voiddestroy() {

}

@Overridepublic voiddoFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain)throwsIOException, ServletException {

HttpServletRequest request=(HttpServletRequest) servletrequest;

HttpServletResponse response=(HttpServletResponse) servletresponse;if(isSecurityRequest(request)) {

filterchain.doFilter(request, response);

}else{

log.info("拒绝来自[" + request.getRemoteAddr() + "]的访问请求:" +request.getRequestURI());

response.setStatus(403);if(isAjaxRequest(request)) {

response.setContentType(_JSON_CONTENT);

response.getWriter().print(_403_JSON);

}else{

response.setContentType(_HTML_CONTENT);

response.getWriter().print(_403_HTML);

}

}

}

@Overridepublic void init(FilterConfig filterconfig) throwsServletException {

String allowedIP= filterconfig.getInitParameter("allowedIP");if (allowedIP != null && allowedIP.length() > 0) {for (String item : allowedIP.split(",\\s*")) {//支持通配符*

if (item.contains("*")) {

String regex= item.replace(".", "\\.").replace("*", "\\d{1,3}");

regexlist.add(regex);

}else{

whitelist.add(item);

}

}

}

}/*** 判断当前请求是否来自可信任的地址

*

*@paramrequest

*@return

*/

private booleanisSecurityRequest(HttpServletRequest request) {

String ip=request.getRemoteAddr();for(String item : whitelist) {if(ip.equals(item))return true;

}for(String item : regexlist) {if(ip.matches(item))return true;

}return false;

}/*** 判断请求是否是AJAX请求

*@paramrequest

*@return

*/

private booleanisAjaxRequest(HttpServletRequest request) {

String header= request.getHeader("X-Requested-With");if (header != null && header.length() > 0) {if ("XMLHttpRequest".equalsIgnoreCase(header))return true;

}return false;

}

}

web.xml增加配置:

securityFilter

com.lichmama.webdemo.filter.SecurityFilter

allowedIP

192.168.5.*

securityFilter

/*

尝试访问,结果如下:

00dfd7b81779dfb7a355fe73317ff075.png

*如何在Filter中获取Response的内容?这个问题之前还真没思考过,搜索了下得知如下方法可行:

1.实现一个PrintWriterWrapper,用于替换ServletResponse中的Writer

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.lichmama.webdemo;importjava.io.PrintWriter;importjava.io.Writer;public class PrintWriterWrapper extendsPrintWriter {privateStringBuilder buff;publicPrintWriterWrapper(Writer writer) {super(writer);

buff= newStringBuilder();

}

@Overridepublic void write(inti) {super.write(i);

buff.append(i);

}

@Overridepublic void write(char[] ac, int i, intj) {super.write(ac, i, j);

buff.append(ac, i, j);

}

@Overridepublic void write(char[] ac) {super.write(ac);

buff.append(ac);

}

@Overridepublic void write(String s, int i, intj) {super.write(s, i, j);

buff.append(s, i, j);

}

@Overridepublic voidwrite(String s) {super.write(s);

buff.append(s);

}

@Overridepublic voidflush() {super.flush();

buff.delete(0, buff.length());

}publicString getContent() {returnbuff.toString();

}

}

View Code

2.实现一个ResponseWrapper,用于替换过滤链(FilterChain)中的ServletResponse:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.lichmama.webdemo;importjava.io.IOException;importjava.io.PrintWriter;importjavax.servlet.http.HttpServletResponse;importjavax.servlet.http.HttpServletResponseWrapper;public class ResponseWrapper extendsHttpServletResponseWrapper {privatePrintWriterWrapper writer;publicResponseWrapper(HttpServletResponse response) {super(response);

}

@Overridepublic PrintWriter getWriter() throwsIOException {if (writer == null)

writer= new PrintWriterWrapper(super.getWriter());returnwriter;

}

}

View Code

3.编写Filter实现获取Response的内容捕获:

packagecom.lichmama.webdemo.filter;importjava.io.IOException;importjavax.servlet.Filter;importjavax.servlet.FilterChain;importjavax.servlet.FilterConfig;importjavax.servlet.ServletException;importjavax.servlet.ServletRequest;importjavax.servlet.ServletResponse;importjavax.servlet.http.HttpServletResponse;importcom.lichmama.webdemo.PrintWriterWrapper;importcom.lichmama.webdemo.ResponseWrapper;public class TestFilter implementsFilter {

@Overridepublic void init(FilterConfig filterconfig) throwsServletException {

}

@Overridepublic voiddoFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain)throwsIOException, ServletException {

ResponseWrapper responsewrapper= newResponseWrapper((HttpServletResponse) servletresponse);

filterchain.doFilter(servletrequest, responsewrapper);

PrintWriterWrapper writerWrapper=(PrintWriterWrapper) responsewrapper.getWriter();//TODO retrieve content from PrintWriterWrapper

String content =writerWrapper.getContent();

}

@Overridepublic voiddestroy() {

}

}

that's it~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值