Consul+Ocelot+Polly在.NetCore中使用(.NET5)-Consul服务注册,服务发现
Consul+Ocelot+Polly在.NetCore中使用(.NET5)-网关Ocelot+Consul
Consul+Ocelot+Polly在.NetCore中使用(.NET5)-Ocelot+Polly缓存、限流、熔断、降级
微服务网关Ocelot加入IdentityServer4鉴权-.NetCore(.NET5)中使用
一、简介
描述:微服务网关中,需要对访问的接口进行身份校验后再转发请求,网关中鉴权的方式有很多种,这里介绍的是常用的IdentityServer4鉴权添加到Ocelot网关中,同时下游的服务也要做身份校验,
防止请求绕过网关直接请求下游服务。
二、创建IdentityServer4项目
这里重点不是说IdentityServer4,所以这里建一个简单的示例项目。
1.创建一个Identity4.Api项目
引入NugGet包
IdentityServer4 IdentityServer4.Storage
这里用的都是4.1.2版本
2.在项目中创建一个config静态类
/// <summary> /// 配置 /// </summary> public class Config { /// <summary> /// 定义作用域 /// </summary> public static IEnumerable<ApiScope> ApiScopes => new ApiScope[] { new ApiScope("gatewayScope"), new ApiScope("scope2") }; public static IEnumerable<ApiResource> ApiResources => new ApiResource[] { new ApiResource("server1","服务1") { //4.x必须写 Scopes = { "gatewayScope" } }, }; public static IEnumerable<Client> Clients => new Client[] { new Client { ClientId = "client_test", ClientName = "测试客户端", AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials, ClientSecrets = { new Secret("secret_test".Sha256()) }, AllowedScopes = { "gatewayScope" } }, }; /// <summary> /// 测试的账号和密码 /// </summary> /// <returns></returns> public static List<TestUser> GetTestUsers() { return new List<TestUser> { new TestUser() { SubjectId = "1", Username = "test", Password = "123456" } }; } }
3.在Startup.cs的ConfigureServices()方法中加入
public void ConfigureServices(IServiceCollection services) { #region 内存方式 services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryApiResources(Config.ApiResources) .AddInMemoryClients(Config.Clients) .AddInMemoryApiScopes(Config.ApiScopes) //4.x新加 .AddTestUsers(Config.GetTestUsers()); #endregion services.AddControllersWithViews(); }
4.在Startup.cs的Configure()方法中加入
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseIdentityServer(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }
到这里一个IdentitySever4的鉴权中心就建好了,运行起来,用Postman测试获取token。
token获取成功,说明IdentityServer4的鉴权中心没问题了。
三、Ocelot中加入IdentityServer4认证
Ocelot网关默认已经集成了Id4的,我们需要做的事情有:
1.在配置中加入IdentityServer4的信息,ocelog.json中加入
{ "Routes": [ { //转发到下游服务地址--url变量 "DownstreamPathTemplate": "/api/{url}", //下游http协议 "DownstreamScheme": "http", //负载方式, "LoadBalancerOptions": { "Type": "RoundRobin" // 轮询 }, //上游地址 "UpstreamPathTemplate": "/T1/{url}", //网关地址--url变量 //冲突的还可以加权重Priority "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ], "UseServiceDisConvery": true, //使用服务发现 "ServiceName": "api", //Consul服务名称 //熔断设置,熔断器使用Polly "QoSOptions": { "ExceptionsAllowedBeforeBreaking": 3, //允许多少个异常请求 "DurationOfBreak": 10000, // 熔断的时间10s,单位为ms "TimeoutValue": 5000 //单位ms,如果下游请求的处理时间超过多少则自动将请求设置为超时 默认90秒 }, //鉴权 "AuthenticationOptions": { "AuthenticationProviderKey": "Bearer", //指定一个key "AllowedScopes": [ "gatewayScope" ] //id4的作用域名称 } } ], "GlobalConfiguration": { //Ocelot应用对外地址 "BaseUrl": "http://172.16.2.9:5200", "ServiceDiscoveryProvider": { //Consul地址 "Host": "172.16.2.84", //Consul端口 "Port": 8500, "Type": "Consul" //由Consul提供服务发现,每次请求Consul } } }
2.把Id4加入到IOC中
添加NuGet包
IdentityServer4.AccessTokenValidation
Ocelot项目Startup.cs中的ConfigureServices()方法加上
public void ConfigureServices(IServiceCollection services) { var authenticationProviderKey = "Bearer"; //这个为上面配置里的key services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddIdentityServerAuthentication(authenticationProviderKey, options => { options.Authority = "http://localhost:5000";//id4服务地址 options.ApiName = "server1";//id4 api资源里的apiname options.RequireHttpsMetadata = false; //不使用https options.SupportedTokens = SupportedTokens.Both; }); services.AddOcelot() .AddConsul() .AddPolly(); }
到这里,Ocelot网关配置Id4就配好了。
3.测试验证
先测试加了Id4后,不带token访问下网关
可以看到,报了401,没权限访问,再试一下把上面id4取到的token带*问。
发现可以访问成功了。这Ocelot中加入Id4校验就完成了。
四、下游服务加入IdentityServer4认证
为什么下游服务要加身份校验呢,因为请求可能绕过网关直接访问下游服务,没有验证就会出问题了。
1.配置
只需要在startup.cs中的ConfigureServices中加入上面的代码,去掉AuthenticationProviderKey
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddIdentityServerAuthentication(options => { options.Authority = "http://localhost:5000";//id4服务地址 options.ApiName = "server1";//id4 api资源里的apiname options.RequireHttpsMetadata = false; //不使用https options.SupportedTokens = SupportedTokens.Both; }); services.AddControllers().AddJsonOptions(cfg => { cfg.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); }); services.AddSingleton<OrderService>(); }
然后在Configure()方法中, app.UseRouting();后面加上 app.UseAuthentication();
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); //Consul注册 app.UseConsul(Configuration); }
然后在要校验的地方加上[Authorize]
2.校验不带token直接访问下游服务
显示没权限,再试带上token直接访问下游服务。
很好,成功访问,然后再试下通过网关访问是否能正常访问。
也成了,全部配置完成!
源码地址:https://github.com/weixiaolong325/Ocelot-Consul-Polly-Id4.Demo