當(dāng)前位置:首頁(yè) > IT技術(shù) > Web編程 > 正文

微服務(wù)網(wǎng)關(guān)Ocelot加入IdentityServer4鑒權(quán)-.NetCore(.NET5)中使用
2021-10-22 10:04:19

?

一、簡(jiǎn)介

微服務(wù)網(wǎng)關(guān)Ocelot加入IdentityServer4鑒權(quán)-.NetCore(.NET5)中使用_微服務(wù)

?

?

?

?

?描述:微服務(wù)網(wǎng)關(guān)中,需要對(duì)訪問(wèn)的接口進(jìn)行身份校驗(yàn)后再轉(zhuǎn)發(fā)請(qǐng)求,網(wǎng)關(guān)中鑒權(quán)的方式有很多種,這里介紹的是常用的IdentityServer4鑒權(quán)添加到Ocelot網(wǎng)關(guān)中,同時(shí)下游的服務(wù)也要做身份校驗(yàn),

? ?   防止請(qǐng)求繞過(guò)網(wǎng)關(guān)直接請(qǐng)求下游服務(wù)。

二、創(chuàng)建IdentityServer4項(xiàng)目

這里重點(diǎn)不是說(shuō)IdentityServer4,所以這里建一個(gè)簡(jiǎn)單的示例項(xiàng)目。

1.創(chuàng)建一個(gè)Identity4.Api項(xiàng)目

引入NugGet包



IdentityServer4
IdentityServer4.Storage


這里用的都是4.1.2版本

2.在項(xiàng)目中創(chuàng)建一個(gè)config靜態(tài)類



/// <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","服務(wù)1")
{
//4.x必須寫(xiě)
Scopes = { "gatewayScope" }
},
};

public static IEnumerable<Client> Clients =>
new Client[]
{
new Client
{
ClientId = "client_test",
ClientName = "測(cè)試客戶端",

AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
ClientSecrets = { new Secret("secret_test".Sha256()) },

AllowedScopes = { "gatewayScope" }
},
};

/// <summary>
/// 測(cè)試的賬號(hào)和密碼
/// </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 內(nèi)存方式
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?}");
});
}


到這里一個(gè)IdentitySever4的鑒權(quán)中心就建好了,運(yùn)行起來(lái),用Postman測(cè)試獲取token。

微服務(wù)網(wǎng)關(guān)Ocelot加入IdentityServer4鑒權(quán)-.NetCore(.NET5)中使用_服務(wù)發(fā)現(xiàn)_02

?

?token獲取成功,說(shuō)明IdentityServer4的鑒權(quán)中心沒(méi)問(wèn)題了。

三、Ocelot中加入IdentityServer4認(rèn)證

Ocelot網(wǎng)關(guān)默認(rèn)已經(jīng)集成了Id4的,我們需要做的事情有:

1.在配置中加入IdentityServer4的信息,ocelog.json中加入





{
"Routes": [
{
//轉(zhuǎn)發(fā)到下游服務(wù)地址--url變量
"DownstreamPathTemplate": "/api/{url}",
//下游http協(xié)議
"DownstreamScheme": "http",
//負(fù)載方式,
"LoadBalancerOptions": {
"Type": "RoundRobin" // 輪詢
},
//上游地址
"UpstreamPathTemplate": "/T1/{url}", //網(wǎng)關(guān)地址--url變量 //沖突的還可以加權(quán)重Priority
"UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
"UseServiceDisConvery": true, //使用服務(wù)發(fā)現(xiàn)
"ServiceName": "api", //Consul服務(wù)名稱
//熔斷設(shè)置,熔斷器使用Polly
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3, //允許多少個(gè)異常請(qǐng)求
"DurationOfBreak": 10000, // 熔斷的時(shí)間10s,單位為ms
"TimeoutValue": 5000 //單位ms,如果下游請(qǐng)求的處理時(shí)間超過(guò)多少則自動(dòng)將請(qǐng)求設(shè)置為超時(shí) 默認(rèn)90秒
},
//鑒權(quán)
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer", //指定一個(gè)key
"AllowedScopes": [ "gatewayScope" ] //id4的作用域名稱
}
}
],
"GlobalConfiguration": {
//Ocelot應(yīng)用對(duì)外地址
"BaseUrl": "http://172.16.2.9:5200",
"ServiceDiscoveryProvider": {
//Consul地址
"Host": "172.16.2.84",
//Consul端口
"Port": 8500,
"Type": "Consul" //由Consul提供服務(wù)發(fā)現(xiàn),每次請(qǐng)求Consul
}
}
}


2.把Id4加入到IOC中

添加NuGet包



IdentityServer4.AccessTokenValidation


Ocelot項(xiàng)目Startup.cs中的ConfigureServices()方法加上



public void ConfigureServices(IServiceCollection services)
{
var authenticationProviderKey = "Bearer"; //這個(gè)為上面配置里的key
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(authenticationProviderKey, options =>
{
options.Authority = "http://localhost:5000";//id4服務(wù)地址
options.ApiName = "server1";//id4 api資源里的apiname
options.RequireHttpsMetadata = false; //不使用https
options.SupportedTokens = SupportedTokens.Both;
});
services.AddOcelot()
.AddConsul()
.AddPolly();
}


  

到這里,Ocelot網(wǎng)關(guān)配置Id4就配好了。

3.測(cè)試驗(yàn)證

先測(cè)試加了Id4后,不帶token訪問(wèn)下網(wǎng)關(guān)

微服務(wù)網(wǎng)關(guān)Ocelot加入IdentityServer4鑒權(quán)-.NetCore(.NET5)中使用_微服務(wù)_03

?

?

?可以看到,報(bào)了401,沒(méi)權(quán)限訪問(wèn),再試一下把上面id4取到的token帶上訪問(wèn)。

微服務(wù)網(wǎng)關(guān)Ocelot加入IdentityServer4鑒權(quán)-.NetCore(.NET5)中使用_微服務(wù)_04

?

?發(fā)現(xiàn)可以訪問(wèn)成功了。這Ocelot中加入Id4校驗(yàn)就完成了。

四、下游服務(wù)加入IdentityServer4認(rèn)證

為什么下游服務(wù)要加身份校驗(yàn)?zāi)?,因?yàn)檎?qǐng)求可能繞過(guò)網(wǎng)關(guān)直接訪問(wèn)下游服務(wù),沒(méi)有驗(yàn)證就會(huì)出問(wèn)題了。

1.配置

只需要在startup.cs中的ConfigureServices中加入上面的代碼,去掉AuthenticationProviderKey



public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";//id4服務(wù)地址
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注冊(cè)
app.UseConsul(Configuration);
}


?

然后在要校驗(yàn)的地方加上[Authorize]

微服務(wù)網(wǎng)關(guān)Ocelot加入IdentityServer4鑒權(quán)-.NetCore(.NET5)中使用_服務(wù)發(fā)現(xiàn)_05

?

?

2.校驗(yàn)不帶token直接訪問(wèn)下游服務(wù)

  微服務(wù)網(wǎng)關(guān)Ocelot加入IdentityServer4鑒權(quán)-.NetCore(.NET5)中使用_.net_06

?

?顯示沒(méi)權(quán)限,再試帶上token直接訪問(wèn)下游服務(wù)。

微服務(wù)網(wǎng)關(guān)Ocelot加入IdentityServer4鑒權(quán)-.NetCore(.NET5)中使用_微服務(wù)_07

?

?

?

?很好,成功訪問(wèn),然后再試下通過(guò)網(wǎng)關(guān)訪問(wèn)是否能正常訪問(wèn)。

微服務(wù)網(wǎng)關(guān)Ocelot加入IdentityServer4鑒權(quán)-.NetCore(.NET5)中使用_直接訪問(wèn)_08

?

也成了,全部配置完成!

?

源碼地址:??https://github.com/weixiaolong325/Ocelot-Consul-Polly-Id4.Demo??

本文摘自 :https://blog.51cto.com/u

開(kāi)通會(huì)員,享受整站包年服務(wù)立即開(kāi)通 >