Forráskód Böngészése

优化-----TokenFilter update

raodeming 3 éve
szülő
commit
ec77e4aba5

+ 5 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/constant/BusinessConstant.java

@@ -11,6 +11,11 @@ public interface BusinessConstant {
     String RIGTH_BIG_BOAST = "}";
     String LEFT_MIDDLE_BOAST = "[";
     String RIGHT_MIDDLE_BOAST = "]";
+    String SLASH = "/";
+
+    String USER_GUEST = "guest";
+    String USER_ADMIN = "admin";
+
 
     /**
      * 字典项重复

+ 75 - 53
report-core/src/main/java/com/anjiplus/template/gaea/business/filter/TokenFilter.java

@@ -1,6 +1,5 @@
 package com.anjiplus.template.gaea.business.filter;
 
-
 import com.alibaba.fastjson.JSONObject;
 import com.anji.plus.gaea.bean.ResponseBean;
 import com.anji.plus.gaea.cache.CacheHelper;
@@ -16,7 +15,6 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 import org.springframework.util.AntPathMatcher;
-import org.springframework.util.CollectionUtils;
 
 import javax.servlet.*;
 import javax.servlet.http.HttpServletRequest;
@@ -24,9 +22,9 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.regex.Pattern;
-import java.util.stream.Collectors;
 
 import static com.anji.plus.gaea.constant.GaeaConstant.URL_REPLACEMENT;
 
@@ -39,23 +37,23 @@ import static com.anji.plus.gaea.constant.GaeaConstant.URL_REPLACEMENT;
 @Order(Integer.MIN_VALUE + 99)
 public class TokenFilter implements Filter {
     private static final Pattern PATTERN = Pattern.compile(".*().*");
-    private static final String USER_GUEST = "guest";
 
-    @Value("${server.servlet.context-path:'/'}")
+    @Value("${server.servlet.context-path:/}")
     private String SLASH = "/";
+    private AntPathMatcher antPathMatcher = new AntPathMatcher();
 
     @Autowired
     private CacheHelper cacheHelper;
     @Autowired
     private JwtBean jwtBean;
 
-    /** 跳过token验证和权限验证的url清单*/
-    @Value("#{'${customer.skip-authenticate-urls}'.split(',')}")
+    /**
+     * 跳过token验证和权限验证的url清单
+     */
+    @Value("#{'${customer.skip-authenticate-urls:}'.split(',')}")
     private List<String> skipAuthenticateUrls;
     private Pattern skipAuthenticatePattern;
 
-    private AntPathMatcher antPathMatcher = new AntPathMatcher();
-
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
         // 生成匹配正则,跳过token验证和权限验证的url
@@ -69,13 +67,25 @@ public class TokenFilter implements Filter {
         HttpServletResponse response = (HttpServletResponse) servletResponse;
         String uri = request.getRequestURI();
 
+        // TODO 暂时先不校验 直接放行
+        /*if (true) {
+            filterChain.doFilter(request, response);
+            return;
+        }*/
+
         //OPTIONS直接放行
         if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
             filterChain.doFilter(request, response);
             return;
         }
 
-        if (SLASH.equals(uri) || SLASH.concat("/").equals(uri)) {
+        // swagger相关的直接放行
+        if (uri.contains("swagger-ui") || uri.contains("swagger-resources")) {
+            filterChain.doFilter(request, response);
+            return;
+        }
+
+        if (SLASH.equals(uri) || SLASH.concat(BusinessConstant.SLASH).equals(uri)) {
             response.sendRedirect(SLASH + "/index.html");
             return;
         }
@@ -125,51 +135,19 @@ public class TokenFilter implements Filter {
             return;
         }
         String gaeaUserJsonStr = cacheHelper.stringGet(userKey);
+        // 延长有效期
+        cacheHelper.stringSetExpire(tokenKey, token, 3600);
+        cacheHelper.stringSetExpire(userKey, gaeaUserJsonStr, 3600);
 
-        //判断接口权限
-        //请求路径
-        //String requestUrl = request.getRequestURI();  requestUrl中可能会有contextpath,而底层扫描的controller是没有的
-        String servletPath = request.getServletPath();
-        String methodValue = request.getMethod();
-        //请求方法+#+请求路径
-        String urlKey = methodValue + GaeaConstant.URL_SPLIT + servletPath;
-
-        GaeaUserDto gaeaUserDto = JSONObject.parseObject(gaeaUserJsonStr, GaeaUserDto.class);
-        List<String> authorities = gaeaUserDto.getAuthorities();
-        Map<String, String> applicationNameAllAuthorities = cacheHelper.hashGet(BusinessConstant.GAEA_SECURITY_AUTHORITIES);
-        AtomicBoolean authFlag = new AtomicBoolean(false);
-        //查询当前请求是否在对应的权限里。即:先精确匹配(保证当前路由是需要精确匹配还是模糊匹配,防止精确匹配的被模糊匹配)
-        // 比如:/user/info和/user/**同时存在,/user/info,被/user/**匹配掉
-        if (applicationNameAllAuthorities.containsKey(urlKey)) {
-            String permissionCode = applicationNameAllAuthorities.get(urlKey);
-            if (authorities.contains(permissionCode)) {
-                authFlag.set(true);
-            }
-        } else {
-            List<String> collect = applicationNameAllAuthorities.keySet().stream()
-                    .filter(key -> StringUtils.isNotBlank(key) && key.contains(URL_REPLACEMENT))
-                    .filter(key -> antPathMatcher.match(key, urlKey)).collect(Collectors.toList());
-            if (CollectionUtils.isEmpty(collect)) {
-                authFlag.set(true);
-            }else {
-                collect.forEach(key -> {
-                    String permissionCode = applicationNameAllAuthorities.getOrDefault(key, "");
-                    if (authorities.contains(permissionCode)) {
-                        authFlag.set(true);
-                    }
-                });
+        // 判断用户是否有该url的权限
+        if (!BusinessConstant.USER_ADMIN.equals(loginName)) {
+            AtomicBoolean authorizeFlag = authorize(request, gaeaUserJsonStr);
+            if (!authorizeFlag.get()) {
+                authError(response);//无权限
+                return;
             }
         }
 
-        if (!authFlag.get()) {
-            //无权限
-            authError(response);
-            return;
-        }
-
-        // 延长有效期
-        cacheHelper.stringSetExpire(tokenKey, token, 3600);
-        cacheHelper.stringSetExpire(userKey, gaeaUserJsonStr, 3600);
 
         //执行
         filterChain.doFilter(request, response);
@@ -205,14 +183,58 @@ public class TokenFilter implements Filter {
         return Pattern.compile(patternString.toString());
     }
 
+    /** 判断用户是否有该接口的权限
+     * @return
+     */
+    private AtomicBoolean authorize(HttpServletRequest request, String gaeaUserJsonStr){
+
+        //判断接口权限
+        //请求路径
+        String requestUrl = request.getRequestURI();
+        if (!BusinessConstant.SLASH.equals(SLASH)) {
+            requestUrl = requestUrl.substring(SLASH.length());
+        }
+        String methodValue = request.getMethod();
+        //请求方法+#+请求路径
+        String path = methodValue + GaeaConstant.URL_SPLIT + requestUrl;
+
+        GaeaUserDto gaeaUserDto = JSONObject.parseObject(gaeaUserJsonStr, GaeaUserDto.class);
+        List<String> userAuthorities = gaeaUserDto.getAuthorities();
+        Map<String, String> authoritiesAllMap = cacheHelper.hashGet(BusinessConstant.GAEA_SECURITY_AUTHORITIES);
+
+        AtomicBoolean authFlag = new AtomicBoolean(false);
+
+        // 接口GET#/gaeaDictItem/pageList
+        if(authoritiesAllMap.containsKey(path)){
+            String permissionCode = authoritiesAllMap.get(path);
+            boolean flag = userAuthorities.contains(permissionCode);
+            authFlag.set(flag);
+            return authFlag;
+        }
+
+        // 接口GET#/accessUser/roleTree/**
+        Optional<String> optionalMatchKey = authoritiesAllMap.keySet().stream()
+                .filter(key -> StringUtils.isNotBlank(key) && key.contains(URL_REPLACEMENT))
+                .filter(key -> antPathMatcher.match(key, path)).findFirst();
+        if(optionalMatchKey.isPresent() == false){
+            authFlag.set(true);
+            return authFlag;
+        }
+        String authoritieKey = optionalMatchKey.get();
+        String needPermission = authoritiesAllMap.get(authoritieKey);
+        boolean flag = userAuthorities.contains(needPermission);
+        authFlag.set(flag);
+        return authFlag;
+    }
+
     private void error(HttpServletResponse response) throws IOException {
-        ResponseBean responseBean = ResponseBean.builder().code("50014").message("The Token has expired").build();
+        ResponseBean responseBean = ResponseBean.builder().code("50008").message("The Token has expired").build();
         response.setContentType(ContentType.APPLICATION_JSON.getMimeType());
         response.getWriter().print(JSONObject.toJSONString(responseBean));
     }
 
     private void authError(HttpServletResponse response) throws IOException {
-        ResponseBean responseBean = ResponseBean.builder().code("User.no.authority").message("没有权限").build();
+        ResponseBean responseBean = ResponseBean.builder().code("User.no.authority").message("no auth").build();
         response.setContentType(ContentType.APPLICATION_JSON.getMimeType());
         response.getWriter().print(JSONObject.toJSONString(responseBean));
     }