自定义SpringMVC拦截器,实现内外网访问控制功能

这篇文章简单介绍如何自定义一个SpringMVC拦截器,并通过拦截器实现具体的功能。

首先,需要创建一个自定义的拦截器类,该类实现HandlerInterceptor接口。

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;

/**
 * 自定义拦截器
 * @author heyunlin
 * @version 1.0
 */
@Slf4j
@Component
public class WebInterceptor implements HandlerInterceptor {

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

    /**
     * 匿名接口权限
     */
    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 {
        // 获取请求url
        String requestURI = request.getRequestURI();

        // 1、处理匿名访问接口,直接跳过鉴权
        if (ANONYMITY_URLS.contains(requestURI)) {
            log.debug("匿名接口" + requestURI + "正在被访问...");

            return true;
        }

        // 2、内外网控制
        if (networkProperties.isEnableInnerIpAccess()) {
            // 得到客户端IP
            String clientIp = IpUtils.getIp();

            if (!networkProperties.getInnerIps().contains(clientIp)) {
                // 构建返回对象
                JsonResult<Void> jsonResult = JsonResult.error(ResponseCode.FORBIDDEN, requestURI + "只允许内网访问~");

                // 设置内容类型为json
                response.setContentType("application/json;charset=utf-8");
                // 设置响应状态码
                response.setStatus(ResponseCode.FORBIDDEN.getValue());
                response.getWriter().write(JSON.toJSONString(jsonResult));

                return false;
            }
        }

        return true;
    }

    /**
     * 获取匿名接口列表
     * @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地址工具类
 * @author heyunlin
 * @version 1.0
 */
public class IpUtils {

    /**
     * 获取客户端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;
    }

    /**
     * 获取浏览器类型
     * @return String 浏览器类型
     */
    public static String getBrowserType() {
        HttpServletRequest request = UserUtils.getRequest();
        String type = "其它";
        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 && browserName.indexOf("rv:11") > 0) {
            type = "IE11";
        }

        return type;
    }

}

然后把拦截器注册到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配置类
 * @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;
    }

    /**
     * 解决跨域问题
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(5000);
    }

    /**
     * 添加静态资源路径
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 配置静态资源路径
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:static/")
                .addResourceLocations("file:" + uploadPath + "/");
        // 解决knife4j访问失败问题
        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("/**");
    }

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

}

猜你喜欢

转载自blog.csdn.net/heyl163_/article/details/134213913