ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java安全代码审计中常见的全局过滤方式

2021-09-16 18:59:50  阅读:214  来源: 互联网

标签:逻辑 Java void 过滤 Aspect Override 全局 public


概述

Spring中常见的全局过滤方式有三种:Filter、Conterceptor、Aspect。

  1. 三者的执行顺序是:Filter > Conterceptor > Aspect。
  2. Filter在请求到达具体的Controller之前执行,所以无法获取到Controller相关的数据,仅仅能处理请求及响应数据流。
  3. Conterceptor可以获取到处理的Controller方法的相关的数据,但是此时的Controller是以静态方法(非动态)的形式出现的。
  4. Aspect可以获取到赋值给处理方法的参数值。
  5. 还有一个自定义参数解析器,可以针对某个参数实现一些特殊过滤逻辑(可能用来从cookie中解析出来真实用户)。

一、过滤器 Filter

属于 javax.servlet.Filter 技术。

1、定义具体逻辑

public class XxxxFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        /*前置过滤逻辑*/
        filterChain.doFilter(servletRequest, servletResponse);
        /*后置过滤逻辑*/
    }
}

2、配置该过滤器

// 1、 web.xml方式配置
    <filter>
        // filter名,随便起
        <filter-name>AdminFilter</filter-name>
        // 实现filter的类
        <filter-class>cn.kihyou.b2c.filter.AdminFilter</filter-class>
        // 初始化参数
        <init-param></init-param>
    </filter>
    
    <filter-mapping>
        // 对应的filter名
        <filter-name>AdminFilter</filter-name>
        // 要进行拦截过滤的目录
        <url-pattern>/api/admin/*</url-pattern>
   </filter-mapping>
   
// 2、注解的形式配置
在 Filter 的实现类上添加 @WebFilter 注解
eg. @WebFilter(filterName="log",urlPatterns={"/*"})

二、拦截器 Conterceptor

属于 org.springframework.web.servlet.HandlerInterceptor 技术。

1、定义具体逻辑:

public class XxxxInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
        /*前置过滤逻辑*/
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, ModelAndView modelAndView) throws Exception {
        // 其中 handler参数为处理该请求的 Controller 方法
        /*后置过滤逻辑1*/
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception e) throws Exception {
        /*后置过滤逻辑2,常用于清理资源*/
    }
}

2、配置该拦截器

// 1、 SpringMVC的配置文件中
<!-- 配置拦截器 -->
<mvc:interceptors>
    <!-- 配置一个全局拦截器,拦截所有请求 -->
    <bean class="interceptor.TestInterceptor" /> 
    <mvc:interceptor>
        <!-- 配置拦截器作用的路径 -->
        <mvc:mapping path="/**" />
        <!-- 配置不需要拦截作用的路径 -->
        <mvc:exclude-mapping path="" />
        <!-- 定义<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
        <bean class="interceptor.Interceptor1" />
    </mvc:interceptor>
</mvc:interceptors>
// 2、注解的形式配置
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
  @Autowired
  private XxxxInterceptor xxxxInterceptor;
  
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(xxxxInterceptor);
    registration.addPathPatterns("/**");     //所有路径都被拦截
    registration.excludePathPatterns("/static/*.html","/static/*.js",)     //添加不拦截的路径
  }
}

Tips:SpringMVC的配置文件有两种方式:

项目中到底使用的是哪一种,需要在在web.xml中查看 <servlet></servlet>配置。

// 1、 指定位置
<servlet>
    <servlet-name>dispatcherSerlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>   // 指定SpringMVC的配置文件是 classess文件夹下的springmvc.xml文件
    </init-param>
</servlet>


// 2、默认位置
<servlet>
    <servlet-name>dispatcherSerlet</servlet-name>    // 默认SpringMVC的配置文件是:在WEB-INF文件夹下的 {此处的servlet-name}-servlet.xml
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>

三、切面 Aspect

属于 org.aspectj.lang.annotation.Aspect 技术。

1、定义作用标识的注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface XxxxXxx {
}

2、定义具体逻辑

@Aspect
@Component
public class XxxxAop{
    //定义切点
    @Pointcut("@annotation(com.xxx.annotation.XxxxXxx)")
    public void audit() {
    }
    
    @Around("audit()")
    public Object handleControllerMethod(ProceedingJoinPoint point) throws Throwable {
        /*前置过滤逻辑*/
        Object returnValue = point.proceed()
        /*后置过滤逻辑*/
    }
    
    @Before("audit()")
    public void before(JoinPoint joinPoint) {
        /*前置过滤逻辑*/
    }
    @After("audit()")
    public void after(JoinPoint joinPoint) {
        /*后置过滤逻辑*/
    }
    
    @AfterReturning()
    public void afterReturning(JoinPoint joinPoint, Object result) {}
    
    @AfterThrowing()
    public void afterThrowing(JoinPoint joinPoint, Throwable exception) {}
}

3、配置启动AOP

// 1、xml文件配置
 <!-- 声明类 ,此类作为切面类使用  -->
 <bean id="logInterceptor" class="com.aop.LogInterceptor" />
 <aop:config>
  <!-- 设置切面名,及切面类 -->
  <aop:aspect id="logAspect" ref="logInterceptor">
  
   <!-- 运行前方法配置,先择要执行的方法 ,并设置切入点  -->
   <aop:before method="before" pointcut="execution(public * com.userService.*.add(..))" />
   
   <!-- 先设置切入点,待使用  -->
   <aop:pointcut id="servicePointcut" expression="execution(public * com.userService.*.add(..))" />
   
   <!-- 运行后方法配置,先择要执行的方法,参考预先设置好的切入点  -->
   <aop:after method="after" pointcut-ref="servicePointcut" />
   
  </aop:aspect>
 </aop:config>


// 2、启动注解配置, Spring默认不支持@Aspect风格的切面声明,通过如下配置开启@Aspect支持
    <aop:aspectj-autoproxy/>  

四、自定以参数解析器

属于 org.springframework.web.method.support.HandlerMethodArgumentResolver 技术。

对于大型项目,通常会有很多引用包,其中封装了一些自定义注解,具体的实现逻辑就需要好好翻翻。

1、定义作用标识的注解

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface XxxxXxx {
}

2、定义具体逻辑

public class XxxxHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        // 用于判定是否需要处理该参数,返回 true 为需要,并会去调用下面的方法resolveArgument。
        return methodParameter.getParameterType().isAssignableFrom(UserParam.class)
                && methodParameter.hasParameterAnnotation(XxxxXxx.class);
    }
    
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        // 具体的得到参数值的逻辑,return 返回参数值
        return value;
    }
}

3、配置该参数解析器

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new XxxxXxxHandlerMethodArgumentResolver());
    }
}

五、寻找非当前项目实现的自定义参数的逻辑代码位置Tips

当前项目声明的自定义参数实现逻辑通过在当前项目文件夹搜索HandlerMethodArgumentResolver 便可快速定位。

第一步、首先找到一个使用位置

第二步、定位到具体的声明位置

第三步、通过 Find Usages 功能查找resolve的相关文件


关注公众号获取更多干货

标签:逻辑,Java,void,过滤,Aspect,Override,全局,public
来源: https://blog.csdn.net/qq_29798597/article/details/120334909

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有