为什么集成在Ocelot中
在上一篇文章中,我们并没有将认证授权集成在Ocelot中,在生产环境中,如果我们每个服务都添加了认证授权,那么在实际部署中肯定会生成很多的配置,就会相对于麻烦。
所以我们就把IdentityServer4加到网关中,客户端的请求通过网关就会进行身份证验证,当网关的身份验证通过之后就会把请求转发给服务集群中,集群就不需要进行身份验证了
项目示例
1. 在网关中引入包
IdentityServer4.AccessTokenValidation
2. 注入服务,这里要在Idr4中新增一个网关的api资源名称,我比较懒,就用的上篇文章创建好了的名称。
注意,这里要给一个Sceme名称,随便取一个就行,方便Ocelot识别
//添加idr4权限 services.AddAuthentication("Bearer") //给当前授权随便起个名称,方便集成到Ocelot里面去 .AddIdentityServerAuthentication("OcelotScheme",options => { options.Authority = "http://localhost:2000"; //授权地址 options.RequireHttpsMetadata = false; options.ApiSecret = "testcode"; //网关资源API秘钥 options.ApiName = "signalrapi"; //网关的资源API名称 });
3. 新加一个测试的Ocelot配置文件 ocelot.Idr4.json , 在之前的路由(ReRoutes)中新增一个认证参数( AuthenticationOptions )配置就行了,这里的 AuthenticationProviderKey 配置为刚才注册服务时随便取的那个Scheme名称
{ "ReRoutes": [ { "DownstreamPathTemplate": "/ConsulHealthCheck/{action}", //下游转发接口 "DownstreamScheme": "http", "ServiceName": "consualapi", "LoadBalancerOptions": { //负载均衡配置 "Type": "LeastConnection" //“轮询”算法 可以配置其他的 }, "UpstreamPathTemplate": "/GateWay/{action}", //上游接口地址 "UpstreamHttpMethod": [ "Get", "Post" ], //限制网关http请求方式 //集成idr4认证 "AuthenticationOptions": { "AuthenticationProviderKey": "OcelotScheme", //配置startup中服务名称 "AllowedScopes": [] } } ], "GlobalConfiguration": { "ServiceDiscoveryProvider": { "Host": "localhost", "Port": 8500, "Type": "Consul" }, "RateLimitOptions": { "DisableRateLimitHeaders": false, "QuotaExceededMessage": "Custom Tips", "HttpStatusCode": 999, "ClientIdHeader": "Test" } } }
4. 在Consul服务中新增一个接口测试
/// <summary> /// 当前登录用户信息 /// </summary> /// <param name="url"></param> /// <returns></returns> [HttpGet("UserInfo")] public async Task<IActionResult> UserInfo() { //根据网关转发过来的token去认证服务获取用户信息 var accessToken=HttpContext.Request.Headers["Authorization"].ToString(); HttpClient client = new HttpClient(); client.BaseAddress = new Uri("http://localhost:2000"); client.DefaultRequestHeaders.Add("Authorization", accessToken); var userinfo = await client.GetAsync("/connect/userinfo"); return Ok($"你正在调用端口号为{Request.HttpContext.Connection.LocalPort}的方法, 用户信息为 { userinfo.Content.ReadAsStringAsync().Result}"); }
运行效果
Ocelot实现 动态路由
如果添加很多个服务,那么会产生很多的Ocelot.xx.json文件,这里就使用动态路由,只有一个Ocelot.json文件。
1. 添加一个动态路由的Json文件( DynamicReOcelot.json ),ReRoutes 和 Aggregates 一定要为空
{ "ReRoutes": [], "Aggregates": [], //单个服务配置限流 "DynamicReRoutes": [ { "ServiceName": "consualapi", "RateLimitRule": { "ClientWhitelist": [], "EnableRateLimiting": true, "Period": "1s", "PeriodTimespan": 3000, "Limit": 3 } } ], "GlobalConfiguration": { "RequestIdKey": null, "ServiceDiscoveryProvider": { "Host": "localhost", "Port": 8500, "Type": "Consul", "Token": null, "ConfigurationKey": null }, "RateLimitOptions": { "ClientIdHeader": "ClientId", "QuotaExceededMessage": null, "RateLimitCounterPrefix": "ocelot", "DisableRateLimitHeaders": false, "HttpStatusCode": 429 }, "QoSOptions": { "ExceptionsAllowedBeforeBreaking": 0, "DurationOfBreak": 0, "TimeoutValue": 0 }, "BaseUrl": null, "LoadBalancerOptions": { "Type": "LeastConnection", "Key": null, "Expiry": 0 }, "DownstreamScheme": "http", "HttpHandlerOptions": { "AllowAutoRedirect": false, "UseCookieContainer": false, "UseTracing": false }, //集成idr4认证 "AuthenticationOptions": { "AuthenticationProviderKey": "OcelotScheme", //配置startup中服务名称 "AllowedScopes": [] } } }
2. 加载动态路由配置文件,替代之前的Ocelot.json文件
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); webBuilder.ConfigureAppConfiguration((hostingContext, config) => { // 1、加载ocelot配置文件 //config.AddJsonFile("ocelot.json"); //2. 动态加载多个服务配置 //config // .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath) // .AddJsonFile("appsettings.json", true, true) // .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true) // .AddOcelot(hostingContext.HostingEnvironment) // .AddEnvironmentVariables(); //3. 动态路由 config.AddJsonFile("DynamicReOcelot.json"); }); });
请求效果:
注意,这里解析逻辑:
1. 客户端发起请求到 http://localhost:7000 的网关
2. 网关在consul服务发现中找到对应的服务名称,后随机返回一个服务名称的地址,这里是 http://localhost:5004
3. 请求的路径除了第一个是服务的名字,后面都是网关下游请求服务的地址,这里是 /ConsulHealthCheck/userinfo
4. 所以实际的请求是 : http://localhost:5004/ConsulHealthCheck/userinfo
标签:core,网关,服务,json,Ocelot,http,net,localhost From: https://www.cnblogs.com/roubaozidd/p/16617047.html