【重构】Spring Cloud OAuth 无Token调用源码封装
背景
重构-改善既有代码的设计,重构的目的是是软件更容易被理解和修改。
书接上回Spring Security OAuth 微服务内部Token传递的源码解析,本篇主要无token 调用过程中,代码的不断完善及其重构过程。
需求很简单如下图,如果资源服务器的提供的接口,客户端不需要身份验证即不需要携带合法令牌也能访问,并且可以实现远程调用的安全性校验。
第一版本
资源服务器设置接口permitall,配置ignore url 即可
ignore-urls:
- /actuator/**
- /v2/api-docs
保证A对外暴露,A --> B 暴露的服务接口安全
- 自定义 @Inner
- 校验逻辑,判断接口请求中是否含有 XX 请求头
/**
* @author lengleng
* <p>
* 服务间接口不鉴权处理逻辑
*/
@Slf4j
@Aspect
@Component
@AllArgsConstructor
public class PigxSecurityInnerAspect {
private final HttpServletRequest request;
@SneakyThrows
@Around("@annotation(inner)")
public Object around(ProceedingJoinPoint point, Inner inner) {
String header = request.getHeader(SecurityConstants.FROM);
if (inner.value() && !StrUtil.equals(SecurityConstants.FROM_IN, header)) {
log.warn("访问接口 {} 没有权限", point.getSignature().getName());
throw new AccessDeniedException("Access is denied");
}
return point.proceed();
}
}
- 网关请求含有XX 的请求头,避免伪造
public class PigxRequestGlobalFilter implements GlobalFilter, Ordered {
private static final String HEADER_NAME = "X-Forwarded-Prefix";
/**
* Process the Web request and (optionally) delegate to the next
* {@code WebFilter} through the given {@link GatewayFilterChain}.
*
* @param exchange the current server exchange
* @param chain provides a way to delegate to the next filter
* @return {@code Mono<Void>} to indicate when request processing is complete
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1. 清洗请求头中from 参数
ServerHttpRequest request = exchange.getRequest().mutate()
.headers(httpHeaders -> {httpHeaders.remove(SecurityConstants.FROM);})
.build();
return chain.filter(exchange.mutate()
.request(newRequest.mutate()
.header(HEADER_NAME, basePath)
.build()).build());
}
@Override
public int getOrder() {
return -1000;
}
}
- 接口使用,首先声明 B服务的这个接口对外暴露
ignore-urls:
- /info/*
- 接口使用,然后在 B服务的这个接口 添加@Inner注解
@Inner
@GetMapping("/info/{username}")
public R info(@PathVariable String username) {
}
重构
- 上边第一版本的问题是,对于A/B 资源服务想对外暴露的接口,需要两步
- 声明在ResourceServerConfigurerAdapter 的 permitall
- B服务要再次添加@inner 注解
实现@Inner 一步到位到位
- 在ignoreU日历 获取全部Controller 中,标志@Inner 注解的请求,自动维护到忽略的URL,减少开发配置
public class PermitAllUrlProperties implements InitializingBean {
private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");
@Autowired
private WebApplicationContext applicationContext;
@Getter
@Setter
private List<String> ignoreUrls = new ArrayList<>();
@Override
public void afterPropertiesSet() {
RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
map.keySet().forEach(info -> {
HandlerMethod handlerMethod = map.get(info);
// 获取方法上边的注解 替代path variable 为 *
Inner method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Inner.class);
Optional.ofNullable(method)
.ifPresent(inner -> info.getPatternsCondition().getPatterns()
.forEach(url -> ignoreUrls.add(ReUtil.replaceAll(url, PATTERN, StringPool.ASTERISK))));
});
}
}
- 核心是通过RequestMappingHandlerMapping 获取全部的路由配置,然后对 Requestmappint 设置的URL 进行规则替换,然后添加到 ignoreurl中,然后在注入到 ResourceServerConfigurerAdapter 进行permitall
- 使用时候,如果是外部暴露
@Inner(value=false)
- 如果仅是服务内部调用暴露
@Inner
总结
欢迎关注我们获得更多的好玩JavaEE 实践

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
死磕 java集合之LinkedBlockingQueue源码分析
问题 (1)LinkedBlockingQueue的实现方式? (2)LinkedBlockingQueue是有界的还是无界的队列? (3)LinkedBlockingQueue相比ArrayBlockingQueue有什么改进? 简介 LinkedBlockingQueue是java并发包下一个以单链表实现的阻塞队列,它是线程安全的,至于它是不是有界的,请看下面的分析。 源码分析 主要属性 // 容量 private final int capacity; // 元素数量 private final AtomicInteger count = new AtomicInteger(); // 链表头 transient Node<E> head; // 链表尾 private transient Node<E> last; // take锁 private final ReentrantLock takeLock = new ReentrantLock(); // notEmpty条件 // 当队列无元素时,take锁会阻塞在notEmpty条件上,等待其它线程...
-
下一篇
从B站的代码泄露事件中,我们能学到些什么?
先声明一下,本文不聊ISSUE中的七七八八,也不聊代码是否写的好,更不聊是不是跟蔡徐坤有关之类的吃瓜内容。仅站在技术人的角度,从这次的代码泄露事件,聊聊在代码的安全管理上,通常都需要做哪些事来预防此类事件的发生。同时,大家在阅读本文的时候,也可以深入思考下,自己团队是否也存在类似的问题,经过这次的事件,是否有必要针对性的做一些优化。 最小权限 “最小权限”原则是我们在学习Linux用户管理时候经常被提到,并且被反复强调的内容。该原则是指每个程序和系统用户都应该具有完成任务所必需的最小权限集合。赋予每一个合法动作最小的权限,就是为了保护数据以及功能避免受到错误或者恶意行为的破坏。 在代码的安全管理上,“最小权限”原则同样适用。但是,从此次的代码泄露内容中可以看到,这一点做的并不好,一起来看看源自泄露代码的README介绍: 从说明中,可以知道这是一个后端项目的大仓库,每个业务线都通过文件夹的方式管理自己的业务模块。那也就是说,每个业务模块的人都是可以看到这个大仓库的。继续看README最后的负责人信息: 可以看到这个大仓库中包含了非常多的业务模块与相关负责人信息。 由于Git的权限管理都...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- MySQL数据库在高并发下的优化方案
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS8编译安装MySQL8.0.19
- Dcoker安装(在线仓库),最新的服务器搭配容器使用