Feign的异步调用或者MQ调用与Security的问题处理;

两大踩坑点:

  一:部分框架自带有查询当前登录人的信息工具,无需各种本地线程栈ThreadLocals取Request啥的折磨自己;

  二:Security自带有uri匹配的工具,没事多翻翻源码,原创方法的执行效率可能并不高;

  1 package com.*.server.order.config;
  2 
  3 import com.*.common.core.utils.*Util;
  4 import com.*.common.core.utils.StringUtils;
  5 import com.*.common.redis.service.RedisService;
  6 import com.*.common.security.starter.configure.*CloudResourceServerConfigure;
  7 import com.*.common.security.starter.properties.*CloudSecurityProperties;
  8 import feign.RequestInterceptor;
  9 import feign.RequestTemplate;
 10 import lombok.extern.slf4j.Slf4j;
 11 import org.springframework.beans.factory.annotation.Autowired;
 12 import org.springframework.context.annotation.Configuration;
 13 import org.springframework.core.annotation.Order;
 14 import org.springframework.util.AntPathMatcher;
 15 import org.springframework.util.ObjectUtils;
 16 
 17 import java.lang.reflect.Field;
 18 import java.util.*;
 19 import java.util.concurrent.atomic.AtomicBoolean;
 20 
 21 /**
 22  * 功能描述:Feign调用异常
 23  *
 24  * @author 唐泽齐
 25  */
 26 @Slf4j
 27 @Configuration
 28 @Order(Integer.MAX_VALUE)
 29 public class FeignConfiguration implements RequestInterceptor {
 30 
 31     @Autowired
 32     private RedisService redisService;
 33     private static String[] patterns;
 34 
 35     @Autowired
 36     public void init(*CloudResourceServerConfigure *CloudResourceServerConfigure) {
 37         try {
 38             log.warn("初始化FeignConfiguration");
 39             Field field = *CloudResourceServerConfigure.class.getDeclaredField("properties");
 40             field.setAccessible(true);
 41             *CloudSecurityProperties properties = (*CloudSecurityProperties) field.get(*CloudResourceServerConfigure);
 42             patterns = properties.getAnonUris().split(",");
 43         } catch (Exception e) {
 44             patterns = new String[]{};
 45         }
 46     }
 47 
 48     @Override
 49     public void apply(RequestTemplate template) {
 50         Map<String, Collection<String>> headers = template.headers();
 51         String currentTokenValue = *Util.getCurrentTokenValue();
 52         if (StringUtils.isEmpty(currentTokenValue) && !checkLogin(template.url())) {
 53             log.info("为" + template.url() + "填充Token:" + redisService.get("admin_token"));
 54             template.header("Authorization", "bearer " + redisService.get("admin_token"));
 55             template.header("GatewayToken", Collections.singleton("bGVjaHVhbmc6Z2F0ZXdheToxMjM0NTY="));
 56         }
 57     }
 58 
 59     //判断当前请求是否本身就不需要登录
 60     private boolean checkLogin(String uri) {
 61         if (ObjectUtils.isEmpty(patterns)) {
 62             return false;
 63         }
 64 
 65         //创建uri新对象
 66         String finalUri = uri + "";
 67         //补充 “/”
 68         if (!uri.startsWith("/")) {
 69             finalUri += "/";
 70         }
 71         // 过滤 “?”之后的
 72         if (uri.indexOf("?") >= 0) {
 73             finalUri = finalUri.substring(0, finalUri.indexOf("?"));
 74         }
 75         // 原子化 返回结果
 76         AtomicBoolean mustLogin = new AtomicBoolean(false);
 77         String finalUri1 = finalUri;
 78         // 另开 方法,增加 逃逸度
 79         Arrays.stream(patterns).forEach(p -> {
 80             //使用 AntPathMatcher 检查
 81             if (new AntPathMatcher().match(p, uri)) {
 82                 mustLogin.set(true);
 83                 return;
 84             }
 85 //                //自己写检验方法
 86 //                if(!doCheck(p,finalUri1)) {
 87 //                    mustLogin.set(true);
 88 //                    return;
 89 //                };
 90         });
 91         return mustLogin.get();
 92     }
 93 
 94     private boolean doCheck(String check, String uri) {
 95         //是否忽略登录
 96         boolean result = true;
 97         try {
 98             Iterator<String> ic = Arrays.stream(check.split("/")).iterator();
 99             Iterator<String> iu = Arrays.stream(uri.split("/")).iterator();
100             for (; ic.hasNext(); ) {
101                 if (!iu.hasNext()) {
102                     result = false;
103                     break;
104                 }
105                 String c = ic.next();
106                 String u = iu.next();
107                 // 处理 /**
108                 if (c.equals("**") && !ic.hasNext()) {
109                     result = true;
110                     break;
111                 }
112                 // 处理 /*
113                 if (c.equals("*") && !ic.hasNext() && !iu.hasNext()) {
114                     result = true;
115                     break;
116                 }
117                 // 处理 /**/
118                 if (c.equals("**") && ic.hasNext() && iu.hasNext()) {
119                     String nextp = ic.next();
120                     while (iu.hasNext()) {
121                         if (nextp.equals(iu.next())) {
122                             break;
123                         }
124                     }
125                     continue;
126                 }
127                 //处理 /*/
128                 if (c.equals("*") && ic.hasNext() && iu.hasNext()) {
129                     continue;
130                 }
131                 if (!c.equals(u)) {
132                     result = false;
133                     break;
134                 }
135             }
136         } catch (Exception e) {
137             log.warn("检查异常,过滤当前规则。check:" + check + " ===> uri:" + uri, e);
138             result = false;
139         }
140         return result;
141     }
142 
143 }
具体代码如下

 

posted on 2021-07-29 15:32  instr  阅读(369)  评论(0编辑  收藏  举报

导航