声明:请勿利用本公众号文章内的相关技术、工具从事非法测试,如因此造成一切不良后果与文章作者及本公众号无关! |
前一篇介绍了JavaWeb的JSP和会话技术,想了解的可以通过下面链接查阅:
JavaWeb之JSP、Cookie、Session
0xNvyao,公众号:安全随笔JavaWeb之JSP、Cookie、Session
本节继续来分享javaweb知识,说一说javaweb三大核心组件的另外两个重要组件:Filter和Listener,这两个组件也是javaweb内存马常用的组件。
目录:
0x01,Filter过滤器
-- Filter概述及简单入门
-- Filter执行流程
-- Filter拦截规则配置
-- Filter过滤器链介绍
0x02,Listener监听器
0x01,Filter过滤器
Filter概述及简单入门
Filter过滤器是JavaWeb三大组件(Servlet、Filter、Listener)之一,Servlet我们之前已经学习过了。Filter过滤器可以将对资源的请求拦截下来,从而实现一些特殊的功能。一般来说,过滤器可以做一些通用的操作,例如:权限控制、统一编码处理、日志记录、安全过滤(如:XssFilter)等等。
我想很多安全从业者应该都听说过XssFilter吧
XSS过滤器的实现
https://www.cnblogs.com/npe/p/8594854.html
简单通过代码来感受一下Filter如何实现的:
1)创建一个类实现Filter接口,并重写接口全部方法
package com.nvyao.web.filter;
import javax.servlet.*;
import java.io.IOException;
public class FilterDemo2 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
2)通过注解配置拦截资源的路径
// /*表示拦截所有的请求
@WebFilter("/*")
3)重写doFilter()方法
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//
System.out.println("doFilter方法被执行了");
// 放行,如果不放行,会被拦住不执行后续的代码
chain.doFilter(request, response);
}
运行看效果:
如果没有通过 chain.doFilter(request, response) 进行放行,效果是:
服务端代码不会执行,页面也就没有回显。
Filter执行流程
Filter的执行流程如下图所示:
-
先执行Filter过滤器中放行前逻辑
-
再放行,访问资源
-
最后回到Filter过滤器执行放行后逻辑
可以通过代码来确认一下这个执行流程:
1)javaweb项目中分别准备一个jsp页面和一个Filter类
jsp页面代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2><%= "Hello World!" %></h2>
</body>
<%
System.out.println("2、服务端程序执行");
%>
</html>
Filter代码:
package com.nvyao.web.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/*")
public class FilterDemo implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("1、放行之前逻辑");
chain.doFilter(request, response);
System.out.println("3、放行之后的逻辑");
}
@Override
public void destroy() {
}
}
2)运行项目,访问上面jsp页面,看看IDEA控制台输出
3)分析放行之前和放行之后的request、response数据
Filter的执行流程搞清楚了,接下来我们在延伸一下,看看在Filter放行逻辑之前,request对象和response对象,思考两个问题:
-
Filter执行放行之前,doFilter方法里面的request对象是否有数据?
-
有数据,封装的是浏览器/客户端的请求数据
-
Filter执行放行之前,doFilter方法里面的response对象是否有数据?
-
没有数据,还没有走到服务端代码执行,所以服务端数据未写入response对象
Filter代码:
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
// 放行前执行逻辑,一般对request请求数据进行处理
System.out.println("1.放行之前");
String username = httpServletRequest.getParameter("username");
System.out.println("放行之前获取的request数据:" + username);
System.out.println("放行之前获取的response数据:" + httpServletResponse.getHeader("hehe"));
// 放行
chain.doFilter(request, response);
// 放行后逻辑,一般对response响应数据进行处理
System.out.println("2.放行之后");
System.out.println("放行之前获取的response数据:" + httpServletResponse.getHeader("hehe"));
}
ServletDemo1代码:
package com.nvyao.web.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/demo1")
public class ServletDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 通过Servlet将Header头塞到response对象中
resp.setHeader("hehe", "haha");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
运行项目,访问/demo1:
通过输出,就验证了前面说的关于request和reponse对象,就是在FIlter执行放行之前,doFilter方法里面的request对象有数据,而reponse对象没数据。因此一般情况下:
-
放行前执行逻辑,一般对request请求数据进行处理 -
放行后逻辑,一般对response响应数据进行处理
Filter拦截规则配置
Filter过滤器的拦截资源可以通过注解方式也可以通过配置文件方式来配置,这一点和Servlet类的资源路径映射是一样的。先简单介绍下拦截规则一般如何配置,然后再介绍下这两种配置方式:
1)拦截规则细分
/path/*: 匹配指定路径下的所有资源。
*.extension: 匹配指定扩展名的资源。
/servletName: 匹配指定 Servlet 名称的资源。
/*: 匹配所有请求。
2)比如指定资源规则
@WebFilter("/hello.jsp")
3)访问/hello.jsp
4)访问/index.jsp
如果是通过Filter配置文件类配置,也是差不多的,会比注解麻烦点,大致如下:
<filter>
<filter-name>Filter2</filter-name>
<filter-class>com.nvyao.web.filter.FilterTest2</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter2</filter-name>
<url-pattern>/hello.jsp</url-pattern>
</filter-mapping>
Filter过滤器链介绍
一个javaweb应用中,可以配置多个Filter过滤器,这多个过滤器就组成了过滤器链。如下图所示:
这种过滤器链的执行流程又是如何呢,其实比较好猜测:
-
先执行Filter1过滤器中放行前逻辑
-
放行
-
执行Filter2过滤器中放行前逻辑
-
放行
-
正式执行服务端资源
-
回到Filter2过滤器的放行后逻辑
-
回到Filter2过滤器的放行后逻辑
同样写个代码来验证一下上面分析的执行流程:
如果存在多个Filter过滤器,执行的先后顺序如何呢?
-
如果是注解配置的过滤器,优先级按照过滤器类名自然排序
-
如果是配置文件方式配置的过滤器,优先级按照配置顺序
0x02,Listener监听器
在 Java Web 应用程序中,监听器(Listener)是一种用于监听 Web 应用程序中事件发生的组件,它可以捕获并响应特定事件。监听器通过实现相应的接口来监听不同类型的事件,从而在事件发生时执行特定的逻辑。
监听器可以监听当application、session、request三个对象的创建、销毁或者往其中添加、修改、删除属性时自动执行代码的功能组件。
网上找到了关于Listener监听器的分类,大致如下图:
大同小异,简单演示下第一个ServletContextListener这个监听器:
ServletContextListener用于监听 Web 应用程序的启动和关闭事件,以及对 Web 应用程序的上下文进行初始化和清理操作。实现 ServletContextListener 接口的类可以在 Web 应用程序启动和关闭时执行特定的逻辑。
package com.nvyao.web.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
public class ContextLoaderListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
// 加载资源
System.out.println("监听器的contextInitialized被执行,初始化相关资源");
}
public void contextDestroyed(ServletContextEvent sce) {
// 回收资源
System.out.println("监听器的contextDestroyed被执行,相关资源被回收");
}
}
当然除了注解方式配置,也可以通过web.xml配置文件配置启用,如下:
<web-app
version="4.0"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:javaee="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
<display-name>Archetype Created Web Application</display-name>
<listener>
<listener-class>com.nvyao.web.listener.ContextLoaderListener</listener-class>
</listener>
</web-app>
好了,至此通过四篇文章介绍了javaweb的基础知识,分别是:
-
http、tomcat、servlet基础知识的介绍及servlet核心组件的详细讲解
-
request请求和response响应两大重要对象的介绍和源码解读
-
jsp技术和会话技术的介绍
-
以及本篇的Filter拦截器和Listener监听器的介绍
接下来会写一个javaweb综合案例,将上面说的四大块整合到一起,加深理解,综合案例讲解完了,我们再去分析javaweb内存马,终于就快要进入我们的正题了,毕竟我们是搞安全的
原文始发于微信公众号(安全随笔):JavaWeb之Filter、Listener组件
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论