两大踩坑点:

  一:部分框架自带有查询当前登录人的信息工具,无需各种本地线程栈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 }

具体代码如下

Feign的异步调用或者MQ调用与Security的问题处理;的更多相关文章

  1. Linux下同步模式、异步模式、阻塞调用、非阻塞调用总结

    转自:http://www.360doc.com/content/13/0117/12/5073814_260691714.shtml 同步和异步:与消息的通知机制有关. 本质区别 现实例子 同步模式 ...

  2. ②SpringCloud 实战:引入Feign组件,完善服务间调用

    这是SpringCloud实战系列中第二篇文章,了解前面第一篇文章更有助于更好理解本文内容: ①SpringCloud 实战:引入Eureka组件,完善服务治理 简介 Feign 是一个声明式的 RE ...

  3. 微服务架构 | 4.2 基于 Feign 与 OpenFeign 的服务接口调用

    目录 前言 1. OpenFeign 基本知识 1.1 Feign 是什么 1.2 Feign 的出现解决了什么问题 1.3 Feign 与 OpenFeign 的区别与对比 2. 在服务消费者端开启 ...

  4. 转 - RPC调用和HTTP调用的区别

    很长时间以来都没有怎么好好搞清楚RPC(即Remote Procedure Call,远程过程调用)和HTTP调用的区别,不都是写一个服务然后在客户端调用么?这里请允许我迷之一笑~Naive!本文简单 ...

  5. RPC调用和HTTP调用的区别

    很长时间以来都没有怎么好好搞清楚RPC(即Remote Procedure Call,远程过程调用)和HTTP调用的区别,不都是写一个服务然后在客户端调用么?这里请允许我迷之一笑~Naive!本文简单 ...

  6. 《oracle每天一练》触发器不能调用或间接调用COMMIT,ROLLBACK等DCL语句

    触发器不能调用或间接调用COMMIT,ROLLBACK等DCL语句 在触发器中不能运行 ddl语句和commit,rollback语句 ddl语句:DDL语句用语定义和管理数据库中的对象,如Creat ...

  7. 反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性、字段),而不去使用Invoke方法)

    反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性.字段),而不去使用Invoke方法)   创建Delegate (1).Delegate.CreateDelegate(Type, ...

  8. php protected只能被继承,不可以在实例中调用,parent::调用父类(子类函数的重载对父类的函数没有影响)

    <?php class a { private function fun1(){ echo 'a1'; } //protected 可以被继承,但是只能在子类中使用,不能被实例化调用 prote ...

  9. 【VB技巧】VB静态调用与动态调用dll详解

    本文“[VB技巧]VB静态调用与动态调用dll详解”,来自:Nuclear'Atk 网络安全研究中心,本文地址:http://lcx.cc/?i=489,转载请注明作者及出处! [[请注意]]:在以下 ...

随机推荐

  1. SpringBoot 之 多环境切换

    方式一:分开多个配置文件 # /src/main/resources/application.yaml server: port: 8080 spring: profiles: active: dev ...

  2. JMeter_实现算法加密

    JMeter有两种方法可以实现算法加密 一.使用__digest自带函数      参数说明: Digest algorithm:算法摘要,可输入值:MD2.MD5.SHA-1.SHA-224.SHA ...

  3. spring boot 启动读取的配置文件优先级

    1.优先级从高到低 1.  file:/config/ 2. file:/ 3. classpath:/config/ 4. classpath:/ 所有位置的application.properti ...

  4. jave 数据类型 float 的 正确赋值

    1.前言 float 是单精度浮点型 ,有效数字8位 ,在机内存占4个字节  [double 是双精度浮点型 ,有效数字16位 ,在机内存占8个字节 ] 2.赋值 float  a=1.3  会编译报 ...

  5. Java日期格式化带来的年份不正确

    BUG现场 一个线上项目之前一直运行得很稳定,从没出过数据错误的问题,但是在2021.12.26这天却"意外"地出现了数据计算错误. 刚开始一头雾水,不知道是什么问题,后来经过日志 ...

  6. kafka学习笔记(七)kafka的状态机模块

    概述 这一篇随笔介绍kafka的状态机模块,Kafka 源码中有很多状态机和管理器,比如之前我们学过的 Controller 通道管理器 ControllerChannelManager.处理 Con ...

  7. 学习javaScript必知必会(1)~js介绍、函数、匿名函数、自调用函数、不定长参数

    一.简单了解一下JavaScript(js) 1.什么是js? js:是网景公司开发的,是基于客户端浏览器, 面向(基于)对象.事件驱动式的页面脚本语言. 2.什么场景下使用到js? 表单验证.页面特 ...

  8. MATLAB中插值算法实现

    %%%1.M文件%(1).以往少的程序可以在命令行窗口进行编码,但大量的程序编排到命令行窗口,%会有造成乱码的危险.(2).如果将命令编成程序存储在一个文件中(M文件),依次运行文件中的命令,则可以重 ...

  9. 《剑指offer》面试题18. 删除链表的节点

    问题描述 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点. 返回删除后的链表的头节点. 注意:此题对比原题有改动 示例 1: 输入: head = [4,5,1,9], val = ...

  10. How to mount Windows network disk in WSL

    Backgroud Mount samba directly in wsl like linux is difficult Password for root@//filesystem.domain/ ...