- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章教你Spring Cloud保证各个微服务之间调用安全性由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
导读:在微服务的架构下,系统会根据业务拆分为多个服务,各自负责单一的职责,在这样的架构下,我们需要确保各api的安全性,也就是说服务不是开放的,而是需要授权才可访问的,避免接口被不合法的请求所访问.
但是在在微服务集群中服务之间暴力的接口,或者对于第三方开放的接口如果不做及安全和认证,后果可想而知.
阅读下文之前思考几个问题:
如下图,三个服务注册到同一个注册中心集群,服务A、B、C之间如果不做任何限制,服务之间的接口基本是互通的.
但是如果A、B、C之间要做服务认证该如何设计?如果外部定制集成服务D接入怎么保证服务的安全性?
假设服务A是组织架构服务,服务B是规则引擎服务,服务C是公式引擎服务,如果B、C请求A服务调用用户信息除了开放接口规定参数。我们如何加入权限认证信息.
目前市面上主要两种方案处理 。
请求头Header中加入认证信息 token,如下图结构所示.
确定服务认证统一在request header 加X-SERVICE-NAME,在服务服务中我们不可能每个服务都会主动去管理基础认证信息,仔细阅读RestTemplate源码不难发现,RestTemplate实现接口InterceptingHttpAccessor,因此我们可以再定义自己的拦截器来统一处理.
feign远程调用请求增加头部信息处理,重新定义 RequestInterceptor 。
public class FeignApiInterceptor implements RequestInterceptor { /** * 统一处理feign的远程调用拦截 */ @Override public void apply(RequestTemplate requestTemplate) { // 远程调用请求增加头部信息处理(简写代码如下) requestTemplate.header("X-SERVICE-NAME", "..."); }}
RestTemplate 提供高度封装的接口,可以让我们非常方便地进行 Rest API 调用。常见的方法如下:
RestTemplate远程调用请求增加头部信息处理,统一处理处理restTemplate的请求拦截.
/** * restTemplate远程调用请求增加头部信息处理 */@Slf4jpublic class RestApiHeaderInterceptor implements ClientHttpRequestInterceptor { /** * 处理restTemplate的请求拦截 */ @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { long startTime = System.currentTimeMillis(); try { HttpHeaders headers = request.getHeaders(); // 远程调用请求增加头部信息处理(简写代码如下) requestTemplate.header("X-SERVICE-NAME", "..."); ClientHttpResponse response = execution.execute(request, body); // 加入链路深度Deep // .... return response; } finally { // do something } }}
服务注册客户端配置 。
@Configuration@EnableFeignClients(basePackages = NamingConstant.BASE_PACKAGE)public class DiscoveryClientConfig { //...... /** * feign请求拦截器 */ @Bean public RequestInterceptor feignInterceptor() { return new FeignApiInterceptor(); } @Bean @LoadBalanced public RestTemplate restTemplate(HttpClient httpClient, Environment environment) { RestTemplate restTemplate = new RestTemplate(); restTemplateBuilder.configure(restTemplate); restTemplate.setRequestFactory(buildFactory(httpClient, environment)); // 加入自定义拦截器 restTemplate.getInterceptors().add(new RestApiHeaderInterceptor()); return restTemplate; } }
拓展补充:
在处理RestTemplate的请求拦截的时候我们也可以追加链路追踪日志,具体对于链路日志的拓展可查阅《微服务分布式架构中,如何实现日志链路跟踪?》 。
简写代码 。
@Slf4jpublic class RestApiHeaderInterceptor implements ClientHttpRequestInterceptor { /** * 处理restTemplate的请求拦截 */ @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { long startTime = System.currentTimeMillis(); try { // 远程调用请求增加头部信息处理 ClientHttpResponse response = execution.execute(request, body); // 获取传递线程变量 Collection<String> values = response.getHeaders() .get(TraceUtil.TRACE_RPCCOUNT); if (!CollectionUtils.isEmpty(values)) { int value = Integer.valueOf(values.iterator().next()); // 链路深度追加 TraceUtil.getRpcCounter().addAndGet(value + 1); } return response; } finally { // 是否开启链路追踪 if (TraceUtil.isTraceLoggerOn()) { // 输出链路日志(接口耗时) TraceUtil.log(StringHelper.join("dt:", System.currentTimeMillis() - startTime, ", TRACE-RPC-", request.getMethod(), ", URI:", request.getURI())); } } }}
读过Spring-Web源码应该知道OncePerRequestFilter过滤器基类,旨在保证在任何 servlet 容器上每个请求分派一次执行。 它提供了一个带有 HttpServletRequest 和 HttpServletResponse 参数的doFilterInternal方法,详细用法可阅读源码.
另一种也出现在它自己的线程中的调度类型是ERROR 。 如果子类希望静态声明是否应该在错误调度期间调用一次,它们可以覆盖shouldNotFilterErrorDispatch() .
getAlreadyFilteredAttributeName方法确定如何识别请求已被过滤。 默认实现基于具体过滤器实例的配置名称.
public abstract class BaseWebFilter extends OncePerRequestFilter { /** * 返回类名,避免filter不被执行 */ @Override protected String getFilterName() { return null; }}
过滤器定义虚拟类, 继承自接口的过滤器。如果声明为springbean,他自动加载到请求过滤链(因为继承了GenericFilterBean接口,spring默认把继承此类的过滤器bean加到web过滤链)中,通过注解@order定义其优先级如果不申明为springbean,又要加入到过滤链中,可以通过FilterRegistrationBean定义,并指定优先级 。
@Overridepublic BaseWebFilter getFilterInstance() { return new BaseWebFilter() { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { // 拦截校验 if (validateToken(request)) { // 校验通过执行下一个lan"j chain.doFilter(request, response); } else { // 封装统一认证失败返回信息 response.setStatus(401); response.setCharacterEncoding( Charset.defaultCharset().displayName()); response.setContentType( MimeTypeUtils.APPLICATION_JSON.toString()); response.getWriter().println(JsonUtil.toJsonString(Response .err("status.401"))); } } };}
针对与validateToken方法这里就不做展开,对于加密方式大同小异,根据自己项目情况来定.
private boolean validateToken(HttpServletRequest request) { if (!needValidate(request)) { return true; } String security = resolveToken(request); if (security == null) { log.info("验证信息缺失,请求地址:{}", request.getRequestURI()); return false; } try { // 解析security加密规则 return true; } catch (Exception e) { log.info("验证信息无效:{},请求地址:{}", security, request.getRequestURI()); return false; } }
回顾整个方案设计与实现,大致可分为以下几个步骤 。
参数加入位置:请求头Header还是请求体Body确定加入范围:@FeignClient客户端、构建RestTemplate以及集成服务远程接口调用确定拦截位置:Web线程拦截器,用于统一处理线程变量,该过滤器执行顺序早于springsecurity的过滤器确定加密/解密方式:加密字符串和解密 。
到此这篇关于教你Spring Cloud保证各个微服务之间调用安全性的文章就介绍到这了,更多相关Spring Cloud微服务调用内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://blog.csdn.net/li1669852599/article/details/119803571 。
最后此篇关于教你Spring Cloud保证各个微服务之间调用安全性的文章就讲到这里了,如果你想了解更多关于教你Spring Cloud保证各个微服务之间调用安全性的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
为了让我的代码几乎完全用 Jquery 编写,我想用 Jquery 重写 AJAX 调用。 这是从网页到 Tomcat servlet 的调用。 我目前情况的类似代码: var http = new
我想使用 JNI 从 Java 调用 C 函数。在 C 函数中,我想创建一个 JVM 并调用一些 Java 对象。当我尝试创建 JVM 时,JNI_CreateJavaVM 返回 -1。 所以,我想知
环顾四周,我发现从 HTML 调用 Javascript 函数的最佳方法是将函数本身放在 HTML 中,而不是外部 Javascript 文件。所以我一直在网上四处寻找,找到了一些简短的教程,我可以根
我有这个组件: import {Component} from 'angular2/core'; import {UserServices} from '../services/UserService
我正在尝试用 C 实现一个简单的 OpenSSL 客户端/服务器模型,并且对 BIO_* 调用的使用感到好奇,与原始 SSL_* 调用相比,它允许一些不错的功能。 我对此比较陌生,所以我可能会完全错误
我正在处理有关异步调用的难题: 一个 JQuery 函数在用户点击时执行,然后调用一个 php 文件来检查用户输入是否与数据库中已有的信息重叠。如果是这样,则应提示用户确认是否要继续或取消,如果他单击
我有以下类(class)。 public Task { public static Task getInstance(String taskName) { return new
嘿,我正在构建一个小游戏,我正在通过制作一个数字 vector 来创建关卡,该数字 vector 通过枚举与 1-4 种颜色相关联。问题是循环(在 Simon::loadChallenge 中)我将颜
我有一个java spring boot api(数据接收器),客户端调用它来保存一些数据。一旦我完成了数据的持久化,我想进行另一个 api 调用(应该处理持久化的数据 - 数据聚合器),它应该自行异
首先,这涉及桌面应用程序而不是 ASP .Net 应用程序。 我已经为我的项目添加了一个 Web 引用,并构建了各种数据对象,例如 PayerInfo、Address 和 CreditCard。但问题
我如何告诉 FAKE 编译 .fs文件使用 fsc ? 解释如何传递参数的奖励积分,如 -a和 -target:dll . 编辑:我应该澄清一下,我正在尝试在没有 MSBuild/xbuild/.sl
我使用下划线模板配置了一个简单的主干模型和 View 。两个单独的 API 使用完全相同的配置。 API 1 按预期工作。 要重现该问题,请注释掉 API 1 的 URL,并取消注释 API 2 的
我不确定什么是更好的做法或更现实的做法。我希望从头开始创建目录系统,但不确定最佳方法是什么。 我想我在需要显示信息时使用对象,例如 info.php?id=100。有这样的代码用于显示 Game.cl
from datetime import timedelta class A: def __abs__(self): return -self class B1(A):
我在操作此生命游戏示例代码中的数组时遇到问题。 情况: “生命游戏”是约翰·康威发明的一种细胞自动化技术。它由一个细胞网格组成,这些细胞可以根据数学规则生存/死亡/繁殖。该网格中的活细胞和死细胞通过
如果我像这样调用 read() 来读取文件: unsigned char buf[512]; memset(buf, 0, sizeof(unsigned char) * 512); int fd;
我用 C 编写了一个简单的服务器,并希望调用它的功能与调用其他 C 守护程序的功能相同(例如使用 ./ftpd start 调用它并使用 ./ftpd stop 关闭该实例)。显然我遇到的问题是我不知
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
我希望能够从 cmd 在我的 Windows 10 计算机上调用 python3。 我已重新安装 Python3.7 以确保选择“添加到路径”选项,但仍无法调用 python3 并使 CMD 启动 P
我是一名优秀的程序员,十分优秀!