Common global filtering methods in Java security code audit

summary

There are three common global filtering methods in Spring: Filter, Conterceptor and Aspect.

  1. The execution order of the three is: Filter > conterceptor > aspect.
  2. Filter is executed before the request reaches the specific Controller, so it cannot obtain the data related to the Controller, and can only process the request and response data flow.
  3. The Conterceptor can obtain the relevant data of the Controller method processed, but the Controller appears in the form of static method (non dynamic).
  4. Aspect can get the parameter value assigned to the processing method.
  5. There is also a custom parameter parser that can implement some special filtering logic for a parameter (which may be used to parse real users from cookie s).

1, Filter

It belongs to javax.servlet.Filter technology.

1. Define specific logic

public class XxxxFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        /*Pre filter logic*/
        filterChain.doFilter(servletRequest, servletResponse);
        /*Post filter logic*/
    }
}

2. Configure this filter

// 1. web.xml configuration
    <filter>
        // filter name, whatever
        <filter-name>AdminFilter</filter-name>
        // Class implementing filter
        <filter-class>cn.kihyou.b2c.filter.AdminFilter</filter-class>
        // Initialization parameters
        <init-param></init-param>
    </filter>
    
    <filter-mapping>
        // Corresponding filter name
        <filter-name>AdminFilter</filter-name>
        // Directory to be intercepted and filtered
        <url-pattern>/api/admin/*</url-pattern>
   </filter-mapping>
   
// 2. Formal configuration of annotations
 stay Filter Add on the implementation class of @WebFilter annotation
eg. @WebFilter(filterName="log",urlPatterns={"/*"})

2, Interceptor Conterceptor

It belongs to org.springframework.web.servlet.HandlerInterceptor technology.

1. Define specific logic:

public class XxxxInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
        /*Pre filter logic*/
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, ModelAndView modelAndView) throws Exception {
        // Where the handler parameter is the Controller method that handles the request
        /*Post filter logic 1*/
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception e) throws Exception {
        /*Post filter logic 2, which is often used to clean up resources*/
    }
}

2. Configure the interceptor

// 1. In the configuration file of spring MVC
<!-- Configuring Interceptors  -->
<mvc:interceptors>
    <!-- Configure a global interceptor to intercept all requests -->
    <bean class="interceptor.TestInterceptor" /> 
    <mvc:interceptor>
        <!-- Configure the path where the interceptor works -->
        <mvc:mapping path="/**" />
        <!-- Configure paths that do not require interception -->
        <mvc:exclude-mapping path="" />
        <!-- definition<mvc:interceptor>Element, which indicates that the request matching the specified path is intercepted -->
        <bean class="interceptor.Interceptor1" />
    </mvc:interceptor>
</mvc:interceptors>
// 2. Formal configuration of annotations
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
  @Autowired
  private XxxxInterceptor xxxxInterceptor;
  
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(xxxxInterceptor);
    registration.addPathPatterns("/**");     //All paths are blocked
    registration.excludePathPatterns("/static/*.html","/static/*.js",)     //Add non intercepted path
  }
}

Tips: there are two ways to configure spring MVC files:

Which one is used in the project? You need to view the < servlet > < / servlet > configuration in web.xml.

// 1. Specify location
<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>   // Specify that the configuration file of spring MVC is the springmvc.xml file under the classess folder
    </init-param>
</servlet>


// 2. Default location
<servlet>
    <servlet-name>dispatcherSerlet</servlet-name>    // The default spring MVC configuration file is {servlet-name}-servlet.xml under the WEB-INF folder
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>

3, Facet Aspect

It belongs to org.aspectj.lang.annotation.Aspect technology.

1. Annotation defining role identification

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

2. Define specific logic

@Aspect
@Component
public class XxxxAop{
    //Define tangent point
    @Pointcut("@annotation(com.xxx.annotation.XxxxXxx)")
    public void audit() {
    }
    
    @Around("audit()")
    public Object handleControllerMethod(ProceedingJoinPoint point) throws Throwable {
        /*Pre filter logic*/
        Object returnValue = point.proceed()
        /*Post filter logic*/
    }
    
    @Before("audit()")
    public void before(JoinPoint joinPoint) {
        /*Pre filter logic*/
    }
    @After("audit()")
    public void after(JoinPoint joinPoint) {
        /*Post filter logic*/
    }
    
    @AfterReturning()
    public void afterReturning(JoinPoint joinPoint, Object result) {}
    
    @AfterThrowing()
    public void afterThrowing(JoinPoint joinPoint, Throwable exception) {}
}

3. Configure startup AOP

// 1. xml file configuration
 <!-- Declare a class that is used as a facet class  -->
 <bean id="logInterceptor" class="com.aop.LogInterceptor" />
 <aop:config>
  <!-- Set the section name and section class -->
  <aop:aspect id="logAspect" ref="logInterceptor">
  
   <!-- Before running method configuration, select the method to be executed and set the entry point  -->
   <aop:before method="before" pointcut="execution(public * com.userService.*.add(..))" />
   
   <!-- Set the entry point first and wait for use  -->
   <aop:pointcut id="servicePointcut" expression="execution(public * com.userService.*.add(..))" />
   
   <!-- After running the method configuration, select the method to be executed first, and refer to the preset entry point  -->
   <aop:after method="after" pointcut-ref="servicePointcut" />
   
  </aop:aspect>
 </aop:config>


// 2. Start annotation configuration. Spring does not support @ Aspect style Aspect declaration by default. Start @ Aspect support through the following configuration
    <aop:aspectj-autoproxy/>  

4, Custom parameter parser

It belongs to org.springframework.web.method.support.HandlerMethodArgumentResolver technology.

For large projects, there are usually many reference packages, which encapsulate some custom annotations, and the specific implementation logic needs to be searched.

1. Annotation defining role identification

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

2. Define specific logic

public class XxxxHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        // It is used to determine whether the parameter needs to be processed. If true is returned, the following method resolveArgument will be called.
        return methodParameter.getParameterType().isAssignableFrom(UserParam.class)
                && methodParameter.hasParameterAnnotation(XxxxXxx.class);
    }
    
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        // The specific logic to get the parameter value. return returns the parameter value
        return value;
    }
}

3. Configure the parser for this parameter

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

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

5, Find the logical code location of custom parameters not implemented in the current project Tips

The custom parameter implementation logic declared by the current project can be quickly located by searching the HandlerMethodArgumentResolver in the current project folder.

The first step is to find a use location

Step 2: locate the specific declaration location

Step 3: find the relevant files of resolve through the find usage function

Pay attention to official account for more dry cargo

Tags: Web Security

Posted on Thu, 16 Sep 2021 17:22:25 -0400 by anthony522