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