diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/SwaggerSecurityFilter.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/SwaggerSecurityFilter.java new file mode 100644 index 00000000..1e3c92d9 --- /dev/null +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/SwaggerSecurityFilter.java @@ -0,0 +1,95 @@ +package com.gitee.sop.servercommon.swagger; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.util.DigestUtils; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; + +/** + * @author tanghc + */ +@Slf4j +public class SwaggerSecurityFilter implements Filter { + + protected List urlFilters = new ArrayList<>(); + + private String secret = "b749a2ec000f4f29"; + + public SwaggerSecurityFilter() { + urlFilters.add(".*?/doc\\.html.*"); + urlFilters.add(".*?/v2/api-docs.*"); + urlFilters.add(".*?/v2/api-docs-ext.*"); + urlFilters.add(".*?/swagger-resources.*"); + urlFilters.add(".*?/swagger-ui\\.html.*"); + urlFilters.add(".*?/swagger-resources/configuration/ui.*"); + urlFilters.add(".*?/swagger-resources/configuration/security.*"); + } + + protected boolean match(String uri) { + boolean match = false; + if (uri != null) { + for (String regex : urlFilters) { + if (uri.matches(regex)) { + match = true; + break; + } + } + } + return match; + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + String uri = request.getRequestURI(); + // 没有匹配到,直接放行 + if (!match(uri)) { + filterChain.doFilter(servletRequest, servletResponse); + } else { + if (validate(request)) { + filterChain.doFilter(servletRequest, servletResponse); + } else { + response.setContentType("text/palin;charset=UTF-8"); + response.setStatus(403); + PrintWriter printWriter = response.getWriter(); + printWriter.write("access forbidden"); + printWriter.flush(); + } + + } + } + + protected boolean validate(HttpServletRequest request) { + String time = request.getParameter("time"); + String sign = request.getParameter("sign"); + if (StringUtils.isAnyBlank(time, sign)) { + return false; + } + String source = secret + time + secret; + String serverSign = DigestUtils.md5DigestAsHex(source.getBytes()); + return serverSign.equals(sign); + } + + @Override + public void destroy() { + + } +} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/SwaggerSupport.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/SwaggerSupport.java index 6097c459..46bfc6ed 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/SwaggerSupport.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/SwaggerSupport.java @@ -30,6 +30,11 @@ public abstract class SwaggerSupport { .build(); } + @Bean + public SwaggerSecurityFilter swaggerSecurityFilter() { + return new SwaggerSecurityFilter(); + } + protected ApiInfo apiInfo() { return new ApiInfoBuilder() .title(getDocTitle()) diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java index 95fd61d5..ee5e9593 100644 --- a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java +++ b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java @@ -16,9 +16,10 @@ import okhttp3.Response; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; -import org.springframework.web.client.RestClientException; +import org.springframework.util.DigestUtils; import org.springframework.web.client.RestTemplate; import javax.annotation.PostConstruct; @@ -49,8 +50,11 @@ public class DocManagerImpl implements DocManager { RestTemplate restTemplate = new RestTemplate(); DocParser swaggerDocParser = new SwaggerDocParser(); + DocParser easyopenDocParser = new EasyopenDocParser(); + private String secret = "b749a2ec000f4f29p"; + @Autowired private Environment environment; @@ -72,21 +76,32 @@ public class DocManagerImpl implements DocManager { } protected void loadDocInfo(ServiceInfoVO serviceInfoVo) { - String url = "http://" + serviceInfoVo.getIpAddr() + ":" + serviceInfoVo.getServerPort() + "/v2/api-docs"; + String query = this.buildQuery(); + String url = "http://" + serviceInfoVo.getIpAddr() + ":" + serviceInfoVo.getServerPort() + "/v2/api-docs" + query; try { ResponseEntity entity = restTemplate.getForEntity(url, String.class); + if (entity.getStatusCode() != HttpStatus.OK) { + throw new IllegalAccessException("无权访问"); + } String docInfoJson = entity.getBody(); JSONObject docRoot = JSON.parseObject(docInfoJson); DocParser docParser = this.buildDocParser(docRoot); DocInfo docInfo = docParser.parseJson(docRoot); docDefinitionMap.put(docInfo.getTitle(), docInfo); - } catch (RestClientException e) { + } catch (Exception e) { // 这里报错可能是因为有些微服务没有配置swagger文档,导致404访问不到 // 这里catch跳过即可 log.warn("读取文档失败, url:{}, msg:{}", url, e.getMessage()); } } + protected String buildQuery() { + String time = String.valueOf(System.currentTimeMillis()); + String source = secret + time + secret; + String sign = DigestUtils.md5DigestAsHex(source.getBytes()); + return "?time=" + time + "&sign=" + sign; + } + protected DocParser buildDocParser(JSONObject rootDoc) { Object easyopen = rootDoc.get("easyopen"); if (easyopen != null) {