The spring boot project adds an interceptor to verify the token to prevent repeated form submissions

Problem encountered: The tester uses the burpsuite tool to capture the form data. When the page clicks to submit the data, the tool burpsuite modifies the intercepted data and simulates sending it, which can still be modified normally. The solution project adds token verification, 

Step 1: Write the token generation and destruction methods first

package com.smartt.api.interceptor;  
  
import java.lang.annotation.*;  
  
@Target(ElementType.METHOD)  
@Retention (RetentionPolicy.RUNTIME)  
@Documented  
public @interface Token {  
   boolean save() default false;  
   boolean remove() default false;  
}  

 TokenInterceptor.java

package com.smartt.api.interceptor;  
  
import java.lang.reflect.Method;  
import java.util.UUID;  
  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
  
import org.springframework.web.method.HandlerMethod;  
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;  
  
public class TokenInterceptor extends HandlerInterceptorAdapter {  
      
    @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
        if (handler instanceof HandlerMethod) {  
            HandlerMethod handlerMethod = (HandlerMethod) handler;  
            Method method = handlerMethod.getMethod();  
            Token annotation = method.getAnnotation(Token.class);  
            if (annotation != null) {  
                boolean needSaveSession = annotation.save();  
                if (needSaveSession) {  
                    request.getSession(false).setAttribute("token", UUID.randomUUID().toString());  
                }  
                boolean needRemoveSession = annotation.remove();  
                if (needRemoveSession) {  
                    if (isRepeatSubmit(request)) {  
                        return false;  
                    }  
                    request.getSession(false).removeAttribute("token");  
                }  
            }  
            return true;  
        } else {  
            return super.preHandle(request, response, handler);  
        }  
    }  
  
    private boolean isRepeatSubmit(HttpServletRequest request) {  
        String serverToken = (String) request.getSession(false).getAttribute("token");  
        if (serverToken == null) {  
            return true;  
        }  
        String clinetToken = request.getParameter("token");  
        if (clinetToken == null) {  
            return true;  
        }  
        if (!serverToken.equals(clinetToken)) {  
            return true;  
        }  
        return false;  
    }  
}  

 Step 2: Write the interceptor of springboot, intercept the corresponding access method address, and perform token verification

package com.smartt.api;  
  
import org.springframework.boot.SpringApplication;  
import org.springframework.context.annotation.ComponentScan;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;  
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;  
  
import com.smartt.api.interceptor.TokenInterceptor;  
  
@Configuration  
@ComponentScan(useDefaultFilters = true)  
public class WebAppConfig extends WebMvcConfigurerAdapter {  
  
    public static void main(String[] args) {    
        SpringApplication.run(WebAppConfig.class, args);    
    }     
        
    /**   
     * Configure the interceptor   
     * @author lance   
     * @param registry   
     */    
    public void addInterceptors(InterceptorRegistry registry) {    
        registry.addInterceptor(new TokenInterceptor()).addPathPatterns("/admin/**");    
    }    
}  

 I wrote the controller access path corresponding to /admin/. If there are multiple different access addresses, you can write  /**   or 

If you write more than one and don't want to block all of them, you can write like this
Multiple interceptors form an interceptor chain  
        // addPathPatterns is used to add interception rules  
        // excludePathPatterns user exclude interception  
        registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/xxx1/**");  
        registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/xxx2/**");

 

  1. Next is the key, use your custom annotation on the controller method that goes to the page you need to submit
  2. delete on the controller method that submits the data
  3. In the last step, you first need to obtain the token in the session on the page and put it in the hidden domain. Finally, if you submit data through ajax, remember to submit the token as a parameter, otherwise the background cannot obtain the token submitted by your page. value, it cannot be compared with the session

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326059417&siteId=291194637