我们在上一篇文章中介绍了swagger加密码的方式和代码。
swagger添加访问密码_zlfjavahome的博客-CSDN博客
但是有的公司有更严格的要求,比如限制IP访问,这篇文章就讲一下如何通过IP进行访问控制,只允许特定的IP地址访问Swagger接口。
第一步,写一个工具类,用来组装返回的json数据
public class CommonTokenHandler {/*** 返回错误信息* @param httpResponse* @param status* @param msg* @param request* @throws Exception*/public void setReturn(HttpServletResponse httpResponse, int status, String msg, HttpServletRequest request) throws Exception {PrintWriter writer = null;httpResponse.setHeader("Access-Control-Allow-Credentials", "true");httpResponse.setHeader("Access-Control-Allow-Origin", request.getAttribute("Access-Control-Allow-Origin") == null?null:request.getAttribute("Access-Control-Allow-Origin").toString());//UTF-8编码httpResponse.setCharacterEncoding("UTF-8");httpResponse.setContentType("application/json;charset=utf-8");Map<String, Object> result = new HashMap<>();result.put("code", status);result.put("msg", msg);JSONObject jsonObject = new JSONObject(result);String json = jsonObject.toString();try {writer = httpResponse.getWriter();writer.print(json);} catch (Exception ex) {ex.printStackTrace();} finally {if (writer != null){writer.close();}}}}
第二步:写一个拦截器,拦截器继承CommonTokenHandler
@Component
@Slf4j
public class SwaggerHandler extends CommonTokenHandler implements HandlerInterceptor {@Autowiredprivate RedisUtil redisUtil;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String requestURI = request.getRequestURI();log.info("requestURI = {}", requestURI);String ipAddr = IpUtils.getIpAddr(request);log.info("请求IP....{}", ipAddr);if (Objects.toString(ipAddr).equals("127.0.0.1")) {return true;}// 这里是自定义redis的keyObject key = redisUtil.get(RedisKeyUtil.swaggerIP());if (key == null || !key.toString().contains(ipAddr)) {String msg = "您的IP" + ipAddr + "没有访问swagger的权限,请先配置!";log.info(msg);setReturn( response, 7002, msg, request);return false;}return true;}
}
IP工具类:
public class IpUtils {public static String getIpAddr(HttpServletRequest request) {String ip = null;if (request != null) {// X-Forwarded-For:Squid 服务代理String ipAddresses = request.getHeader("X-Forwarded-For");if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {// Proxy-Client-IP:apache 服务代理ipAddresses = request.getHeader("Proxy-Client-IP");}if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {// WL-Proxy-Client-IP:weblogic 服务代理ipAddresses = request.getHeader("WL-Proxy-Client-IP");}if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {// HTTP_CLIENT_IP:有些代理服务器ipAddresses = request.getHeader("HTTP_CLIENT_IP");}if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {// X-Real-IP:nginx服务代理ipAddresses = request.getHeader("X-Real-IP");}// 有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IPif (ipAddresses != null && ipAddresses.length() != 0) {ip = ipAddresses.split(",")[0];}// 还是不能获取到,最后再通过request.getRemoteAddr();获取if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {ip = request.getRemoteAddr();}return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;}return null;}
}
第三步,使用拦截器,新增拦截器配置类MyWebAppConfigurer,将swaggerHandler添加到拦截器链,对doc.html、swagger-ui.html同时拦截
@Configuration
@AutoConfigureOrder(-1)
public class MyWebAppConfigurer implements WebMvcConfigurer {@Autowiredprivate SwaggerHandler swaggerHandler;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 多个拦截器组成一个拦截器链// addPathPatterns 用于添加拦截规则// excludePathPatterns 用户排除拦截registry.addInterceptor(swaggerHandler).addPathPatterns("/**/doc.html/**", "/**/swagger-ui.html/**","/swagger-resources/**","/swagger-ui/**");}/*** 修改StringHttpMessageConverter默认配置** @param converters*/@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}}
通过以上配置,就可以实现IP限制访问了,亲测可用!