Customize SpringMVC interceptor to implement internal and external network access control functions

This article briefly introduces how to customize a SpringMVC interceptor and implement specific functions through the interceptor.

First, you need to create a custom interceptor class that implements the HandlerInterceptor interface.

package cn.edu.sgu.www.mhxysy.interceptor;

import cn.edu.sgu.www.mhxysy.feign.FeignService;
import cn.edu.sgu.www.mhxysy.property.NetworkProperties;
import cn.edu.sgu.www.mhxysy.restful.JsonResult;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.util.IpUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Custom interceptor
 * @author heyunlin
 * @version 1.0
 */
@Slf4j
@Component
public class WebInterceptor implements HandlerInterceptor {

    @Value("${spring.application.name}")
    private final String service = "mhxysy";

    /**
     * Anonymous interface permissions
     */
    private static Set<String> ANONYMITY_URLS;

    private final NetworkProperties networkProperties;

    @Autowired
    public WebInterceptor(FeignService feignService, NetworkProperties networkProperties) {
        this.networkProperties = networkProperties;

        if (ANONYMITY_URLS == null) {
            List<String> permissions = feignService.selectAnonymityPermissions(service);

            ANONYMITY_URLS = new HashSet<>(permissions);
        }
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        // Get the request url
        String requestURI = request.getRequestURI();

        // 1. Process the anonymous access interface and skip authentication directly.
        if (ANONYMITY_URLS.contains(requestURI)) {
            log.debug("anonymous interface" + requestURI + "being accessed...");

            return true;
        }

        // 2. Internal and external network control
        if (networkProperties.isEnableInnerIpAccess()) {
            // Get client IP
            String clientIp = IpUtils.getIp();

            if (!networkProperties.getInnerIps().contains(clientIp)) {
                //Construct the return object
                JsonResult<Void> jsonResult = JsonResult.error(ResponseCode.FORBIDDEN, requestURI + "Only intranet access is allowed~");

                //Set the content type to json
                response.setContentType("application/json;charset=utf-8");
                //Set response status code
                response.setStatus(ResponseCode.FORBIDDEN.getValue());
                response.getWriter().write(JSON.toJSONString(jsonResult));

                return false;
            }
        }

        return true;
    }

    /**
     * Get the anonymous interface list
     * @return Set<String>
     */
    public static Set<String> getAnonymityUrls() {
        return ANONYMITY_URLS;
    }

}

IpUtils.java

package cn.edu.sgu.www.mhxysy.util;

import javax.servlet.http.HttpServletRequest;

/**
 * IP address tool class
 * @author heyunlin
 * @version 1.0
 */
public class IpUtils {

    /**
     * Get client IP
     * @return String
     */
    public static String getIp() {
        HttpServletRequest request = UserUtils.getRequest();
        String ip = request.getHeader("x-forwarded-for");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        return ip;
    }

    /**
     * Get browser type
     * @return String browser type
     */
    public static String getBrowserType() {
        HttpServletRequest request = UserUtils.getRequest();
        String type = "Other";
        String browserName = request.getHeader("USER-AGENT").toLowerCase();

        if (browserName.indexOf("msie") > 0) {
            type = "IE";
        } else if (browserName.indexOf("firefox") > 0) {
            type = "Firefox";
        } else if (browserName.indexOf("chrome") > 0) {
            type = "Chrome";
        } else if (browserName.indexOf("opera") > 0) {
            type = "Opera";
        } else if (browserName.indexOf("gecko") > 0 & amp; & amp; browserName.indexOf("rv:11") > 0) {
            type = "IE11";
        }

        return type;
    }

}

Then register the interceptor to SpringMVC

package cn.edu.sgu.www.mhxysy.config;

import cn.edu.sgu.www.mhxysy.interceptor.WebInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.ServletContext;

/**
 * springmvc configuration class
 * @author heyunlin
 * @version 1.0
 */
@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {

    @Value("${uploads.path}")
    private String uploadPath;

    private final WebInterceptor webInterceptor;

    @Autowired
    public SpringMvcConfig(WebInterceptor webInterceptor) {
        this.webInterceptor = webInterceptor;
    }

    /**
     * Solve cross-domain issues
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(5000);
    }

    /**
     * Add static resource path
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //Configure static resource path
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:static/")
                .addResourceLocations("file:" + uploadPath + "/");
        // Solve the problem of knife4j access failure
        registry.addResourceHandler("doc.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(webInterceptor).addPathPatterns("/**");
    }

    /**
     * Set SESSION_ID
     * @return ServletContextInitializer
     */
    @Bean
    public ServletContextInitializer servletContextInitializer() {
        return new ServletContextInitializer() {
            @Override
            public void onStartup(ServletContext servletContext) {
                servletContext.getSessionCookieConfig().setName("MHXYSY_JSESSIONID");
            }
        };
    }

}