第11章初識IdentityServer4-創(chuàng)新互聯(lián)

1 構(gòu)建IdentityServer4 服務(wù)

創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比裕民網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式裕民網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋裕民地區(qū)。費(fèi)用合理售后完善,10余年實(shí)體公司更值得信賴。

1.1 通過配置類配置類(Config)實(shí)例化IdentityServer4中間件

using IdentityServer4.Models;

namespace BuilderServer

{

///

/// 【配置--類】

///

/// 摘要:

///??? 通過該中類的方法成員,對過“IdentityServer4”中間件進(jìn)行配置設(shè)定,并根據(jù)這些配置設(shè)定。實(shí)例化“IdentityServer4”服務(wù)。

/// 說明:

///???? 配置數(shù)據(jù)最好定義在“appsettings.json”文件中,而非直接嵌入定義在該配置類。

///

///

public static class Config

{

///

/// 【獲取標(biāo)識資源數(shù)組】

///

/// 摘要:

///??? 獲取認(rèn)證用戶的多個證件單元(Claims:包含:如用戶ID、賬戶、電子郵件地址等)實(shí)例,并把這些實(shí)例存儲到數(shù)組實(shí)例中,為通過“IdentityServer4”中間件實(shí)現(xiàn)身份認(rèn)證服務(wù)提供數(shù)據(jù)支撐。

///

///

/// 返回:

///??? 數(shù)組實(shí)例,該數(shù)組實(shí)例中存儲著多個證件單元(Claims:包含:如用戶ID、賬戶、電子郵件地址等)實(shí)例。

///

///

public static IEnumerableGetIdentityResourceArray()

{

return new IdentityResource[]

{

???? new IdentityResources.OpenId(),

???? new IdentityResources.Profile(),

};

}

///

/// 【獲取作用數(shù)組】

///

/// 摘要:

///??? 獲取序中的Api控制器方法分類實(shí)例,并把這些實(shí)例存儲到數(shù)組實(shí)例中,為通過“IdentityServer4”中間件實(shí)現(xiàn)身份認(rèn)證服務(wù)提供數(shù)據(jù)支撐。

/// 應(yīng)用場景:

///???? 在由于前端版本迭代,而需要更新Api控制器方法時,為了兼容舊的前端就需要“Api版本”控制在不修改舊的Api控制器方法,而是定義新的Api控制器方法,來解決前端版本迭代的兼容性問題。

///

///

/// 返回:

????///??? 數(shù)組實(shí)例,該數(shù)組實(shí)例中存儲著Api控制器方法分類的多個實(shí)例。

///

///

public static IEnumerable GetApiScopeArray()

{

return new ApiScope[]

{

???? new ApiScope("api1"),

};

}

///

/// 【獲取客戶端數(shù)組】

///

/// 摘要:

///??? 通過“IdentityServer4”中間件,實(shí)例化多個客戶端實(shí)例(客戶端通過1個指定的客戶端實(shí)例獲取Token),并把實(shí)例存儲到數(shù)組實(shí)例中。

///

///

/// 返回:

///??? 數(shù)組實(shí)例,該數(shù)組實(shí)例中存儲著多個客戶端實(shí)例(客戶端通過1個指定的客戶端實(shí)例獲取Token)。

///

///

public static IEnumerableGetClientArray()

{

return new Client[]

{

???? //客戶端以“client_credentials”方式獲取獲取Token。

???? new Client

???? {

???????? ClientId = "ClientCredential",

???????? ClientName = "客戶端憑證認(rèn)證",

???????? //grant_type:ClientCredential

??????????//Postman->Body->x-www-form-urlencoded參數(shù):

???????? //client_id:ClientCredential

???????? //client_secret:511536EF-F270-4058-80CA-1C89C192F69A

???????? //grant_type:client_credentials

???????? AllowedGrantTypes = GrantTypes.ClientCredentials,

???????? ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },

???????? AllowedScopes = { "api1" },

???????? AccessTokenLifetime = 120 //過期時間=2分鐘,默認(rèn)值:3600秒=1小時。

???? },

????? //客戶端以“password”方式獲取獲取Token。

???? new Client

???? {

???????? ClientId = "PasswordClient",

???????? ClientName = "客戶端密碼認(rèn)證",

???????? //grant_type:password

???????? //Postman->Body->x-www-form-urlencoded參數(shù):

???????? //client_id:PasswordClient

???????? //client_secret:511536EF-F270-4058-80CA-1C89C192F69A

???????? //grant_type:password

???????? //username:zz

???????? //password :123456,

???????? AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,

???????? ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },

???????? AllowedScopes = { "api1" },

???????? AccessTokenLifetime = 120 //過期時間=2分鐘,默認(rèn)值3600秒=1小時。

???? },

? };

}

}

}

1.2 為“IdentityServer4”服務(wù)添加測試性用戶

using IdentityModel;

using IdentityServer4.Test;

using IdentityServer4;

using System.Security.Claims;

using System.Text.Json;

namespace BuilderServer

{

///

/// 【測試用戶--類】

///

/// 摘要:

///??? 通過該類中的方法成員,獲取測試用戶類的多個實(shí)例,并把實(shí)例存儲到列表實(shí)例中,為測試指定用戶通過“IdentityServer4”服務(wù)獲取Token,測試性的用戶。

///

///

public class TestUsers

{

///

/// 【獲取客戶列表】

///

/// 摘要:

///??? 獲取測試用戶類的多個實(shí)例,并把實(shí)例存儲到列表實(shí)例中,為測試指定用戶通過“IdentityServer4”服務(wù)獲取Token,測試性的用戶。

///

///

/// 返回:

///??? 列表實(shí)例,該列表實(shí)例中存儲著測試用戶類的多個實(shí)例。

///

///

public static ListGetUserList()

{

var address = new

{

???? street_address = "金水區(qū)",

???? locality = "鄭州",

???? postal_code = 69118,//郵編。

???? country = "中國"

};

//把測試用戶類的多個實(shí)例存儲到列表實(shí)例中,為測試指定用戶通過“IdentityServer4”服務(wù)獲取Token,測試性的用戶。

return new List

{

???? new TestUser

???? {

???????? SubjectId = "1",

???????? Username = "zz",

???????? Password = "123456",

???????? //通過證件單元,構(gòu)建整個證件。

???????? Claims =

???????? {

???????????? new Claim(JwtClaimTypes.Name, "zz"),

???????????? new Claim(JwtClaimTypes.Email, "zz@email.com"),

???????????? new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean),

???????????? new Claim(JwtClaimTypes.Address, JsonSerializer.Serialize(address), IdentityServerConstants.ClaimValueTypes.Json)

???????? }

???? }

};

}

}

}

1.3 重構(gòu)Program類

//通過配置類中的數(shù)據(jù)實(shí)例,實(shí)例化過“IdentityServer4”中間件,最后把過“IdentityServer4”中間件依賴注入到內(nèi)置容器中,實(shí)現(xiàn)當(dāng)前程序據(jù)這些配置設(shè)定,實(shí)例化“IdentityServer4”服務(wù)。

builder.Services.AddIdentityServer()

?.AddTestUsers(TestUsers.GetUserList())//為“IdentityServer4”服務(wù)添加測試性用戶。

?.AddInMemoryIdentityResources(Config.GetIdentityResourceArray()) // 為“IdentityServer4”服務(wù)添加測試性用戶。

?.AddInMemoryApiScopes(Config.GetApiScopeArray())//指定客戶端所調(diào)用Api控件器方法的作用域(版本)

?.AddInMemoryClients(Config.GetClientArray())//1個指定的客戶端實(shí)例獲取Token的認(rèn)證方式。

?.AddDeveloperSigningCredential();//臨時生成的證書證書。

var app = builder.Build();

// 把“IdentityServer4”管道中間件集成到.Net7框架內(nèi)置管道中,以實(shí)現(xiàn)前程序?qū)Α癐dentityServer4”服務(wù)的支持。

app.UseIdentityServer();

// Configure the HTTP request pipeline.

if (app.Environment.IsDevelopment())

{

? app.UseSwagger();

? app.UseSwaggerUI();

}

app.UseHttpsRedirection();

app.UseAuthorization();

//把內(nèi)置授權(quán)管道中間件集成到.Net7框架內(nèi)置管道中。

//注意:

//內(nèi)置授權(quán)管道中間件必須集成在“IdentityServer4”服務(wù)程序中,否則在使用Postman調(diào)試經(jīng)過認(rèn)證特性標(biāo)記的Api控制器方法時會出現(xiàn):“401Unauthorized”錯誤。

app.UseAuthentication();

1.4 通過Postman測試IdentityServer4服務(wù)

2 通過“IdentityServer4.AccessTokenValidation”中間件獲取IdentityServer4服務(wù)所發(fā)送的“JwtBearer”令牌(Token)實(shí)例

2.1 TestController控制器

using IdentityModel.Client;

using Microsoft.AspNetCore.Authorization;

using Microsoft.AspNetCore.Mvc;

namespace AccessToken.Controllers

{

///

/// 【登錄管Api控制器--類--無認(rèn)證特性標(biāo)記】

///

///

/// 摘要:

///???? 通過該類中的方法成員,用于對IdentityServer4服務(wù)驗證。

///

[Route("api/[controller]")]

[ApiController]

public class TestController : ControllerBase

{

///

/// 【Swagger登錄--無認(rèn)證特性標(biāo)記】

///

///

/// 摘要:

///???? 獲取通過IdentityServer4服務(wù)所發(fā)送的“JwtBearer”令牌(Token)實(shí)例的字符串值。

///

///

/// 返回:

///??? 令牌(Token)實(shí)例的字符串值。

///

[HttpGet("GetToken")]

public async TaskGetToken()

{

//獲取IdentityServer4服務(wù)中的客戶端實(shí)例。

var client = new HttpClient();

var config = new DiscoveryDocumentRequest()

{

???? Address = "https://localhost:44360/",

???? Policy = new DiscoveryPolicy() { RequireHttps = false }

};? //忽略IP或域名時Https請求

var disco = await client.GetDiscoveryDocumentAsync(config);

//根據(jù)IdentityServer4服務(wù)中的客戶端實(shí)例,獲取“JwtBearer”令牌(Token)實(shí)例。

var tokenResponse = await client.RequestClientCredentialsTokenAsync(

???? new ClientCredentialsTokenRequest

???? {

???????? Address = disco.TokenEndpoint,

???????? ClientId = "ClientCredential",

???????? ClientSecret = "511536EF-F270-4058-80CA-1C89C192F69A",

???????? Scope = "api1",

???? });

if (tokenResponse.IsError)

????????{

???? return tokenResponse.Error;

}

//返回“JwtBearer”令牌(Token)實(shí)例的字符串值。

return tokenResponse.AccessToken;

}

///

/// 【Swagger登錄--有認(rèn)證特性標(biāo)記】

///

///

/// 摘要:

///??? 在通過IdentityServer4服務(wù)所發(fā)送的“JwtBearer”令牌(Token)實(shí)例認(rèn)證并授權(quán)后,獲取當(dāng)前Api方法的實(shí)例值。

///

///

/// 返回:

///??? 當(dāng)前Api方法的實(shí)例值。

///

[Authorize("api1")]

[HttpGet("GetValue")]

public IEnumerableGetValue()

{

return new string[] { "value1", "value2" };

}

}

}

2.2 重構(gòu)Program類

using Microsoft.IdentityModel.Tokens;

using Microsoft.OpenApi.Models;

using System.Reflection;

using System.Text;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle

builder.Services.AddEndpointsApiExplorer();

//通過“IdentityServer4.AccessTokenValidation”中間件,把“JwtBearer”中間件注入.Net7框架內(nèi)置容器中,

builder.Services.AddAuthentication("Bearer")

? .AddIdentityServerAuthentication(options =>

? {

? options.Authority = "https://localhost:44360/";//鑒權(quán)(認(rèn)證)服務(wù)地址

? options.RequireHttpsMetadata = false;

? //緩沖過期時間,“JwtBearer”令牌(Token)的總有效時間等于該時間加上jwt的過期時間,緩沖過期時間的默認(rèn)值為“5分鐘”,

? //當(dāng)前把緩沖過期時間設(shè)定為:0,指定令牌(Token)的總有效時間即為jwt的過期時間。

? //注意:

? //如果不設(shè)定“JwtBearer”緩沖過期時間設(shè)定為:0,即在IdentityServer4服務(wù)中的時間(120秒之后)過期后,經(jīng)過認(rèn)證特性標(biāo)記的Api控制器方法依然可以獲取其值,因為還“5分鐘”的緩沖過期。

? options.JwtValidationClockSkew = TimeSpan.FromSeconds(0);

? });

//通過.Net7框架內(nèi)置認(rèn)證中間件,把"api1"策略注入.Net7框架內(nèi)置容器中,

builder.Services.AddAuthorization(option =>

{

? option.AddPolicy("Api1", builder =>

? {

? builder.RequireAuthenticatedUser();

? builder.RequireClaim("scope", "api1");

? });

});

//通過AddSwaggerGen依賴注入中間,獲取Api控制器方法的版本控制信息和注釋等數(shù)據(jù)信息,依賴注入.Net7框架的內(nèi)置容器中,為在“index.html”頁面上渲染顯示這些信息,作好預(yù)處理操作。

builder.Services.AddSwaggerGen(options =>

{

? options.SwaggerDoc("v1", new OpenApiInfo { Title = "IdentityServer4.AccessTokenValidation", Version = "v1" });

? //獲取"AccessToken.xml"文件的文件名。

? string _xmlFileName = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";

? //獲取"SecondPracticeServer.xml"文件的絕對路徑。

? string _xmlFilePath = Path.Combine(AppContext.BaseDirectory, _xmlFileName);

? //把控件器行為方法中的注釋信息加載到"Swagger/index.html"頁面中的控件器行為方法進(jìn)行渲染顯示。

? options.IncludeXmlComments(_xmlFilePath, true);

});

var app = builder.Build();

app.UseSwagger();

app.UseSwaggerUI();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

2.3 通過Postman驗證“IdentityServer4”服務(wù)及其授權(quán)

2.3.1 先通過Postman獲取“JwtBearer”令牌(Token)

2.3.2 通過Headers授權(quán)認(rèn)證特性標(biāo)記的Api控制器方法

2.3.3通過Authorization授權(quán)認(rèn)證特性標(biāo)記的Api控制器方法

3 通過“IdentityModel”中間件獲取IdentityServer4服務(wù)所發(fā)送的“JwtBearer”令牌(Token)實(shí)例

1、通過Nuget引用:IdentityModel包。

2、通過Nuget引用:Microsoft.AspNetCore.Authentication.JwtBearer包。

3.1 重構(gòu)Program類

//通過“Microsoft.AspNetCore.Authentication.JwtBearer”中間件,把“JwtBearer”中間件注入.Net7框架內(nèi)置容器中,

builder.Services.AddAuthentication("Bearer")

? .AddJwtBearer("Bearer", options =>

? {

? options.Authority = "https://localhost:44360/";

? options.RequireHttpsMetadata = false;

? options.TokenValidationParameters = new TokenValidationParameters

? {

? //指示是否對指定令牌(Token)的過期時間進(jìn)行限定,當(dāng)前設(shè)定為:true,即限定。

? RequireExpirationTime = true,

? //指示是否對指定令牌(Token)的生命周期進(jìn)行自動管理,當(dāng)前設(shè)定為:true,即管理,

? //當(dāng)前指定令牌(Token)的生命周期結(jié)束時,程序必須重新生成1個新的指定令牌(Token)才能方法授權(quán)頁面。

? //使用當(dāng)前時間與Token的Claims中的NotBefore和Expires對比后,進(jìn)行管理。

? ValidateLifetime = true,

? //緩沖過期時間,“JwtBearer”令牌(Token)的總有效時間等于該時間加上jwt的過期時間,緩沖過期時間的默認(rèn)值為“5分鐘”,

? //當(dāng)前把緩沖過期時間設(shè)定為:0,指定令牌(Token)的總有效時間即為jwt的過期時間。

? //注意:

? //如果不設(shè)定“JwtBearer”緩沖過期時間設(shè)定為:0,即在IdentityServer4服務(wù)中的時間(120秒之后)過期后,經(jīng)過認(rèn)證特性標(biāo)記的Api控制器方法依然可以獲取其值,因為還“5分鐘”的緩沖過期。

? ClockSkew = TimeSpan.FromSeconds(0),

? };

? });

//通過.Net7框架內(nèi)置認(rèn)證中間件,把"api1"策略注入.Net7框架內(nèi)置容器中,

builder.Services.AddAuthorization(option =>

{

? option.AddPolicy("Api1", builder =>

? {

? builder.RequireAuthenticatedUser();

? builder.RequireClaim("scope", "api1");

? });

});

//通過AddSwaggerGen依賴注入中間,獲取Api控制器方法的版本控制信息和注釋等數(shù)據(jù)信息,依賴注入.Net7框架的內(nèi)置容器中,為在“index.html”頁面上渲染顯示這些信息,作好預(yù)處理操作。

builder.Services.AddSwaggerGen(options =>

{

? options.SwaggerDoc("v1", new OpenApiInfo { Title = "IdentityServer4.AccessTokenValidation", Version = "v1" });

? //獲取"AccessToken.xml"文件的文件名。

? string _xmlFileName = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";

? //獲取"SecondPracticeServer.xml"文件的絕對路徑。

? string _xmlFilePath = Path.Combine(AppContext.BaseDirectory, _xmlFileName);

? //把控件器行為方法中的注釋信息加載到"Swagger/index.html"頁面中的控件器行為方法進(jìn)行渲染顯示。

? options.IncludeXmlComments(_xmlFilePath, true);

});

3.2 通過Postman驗證“IdentityServer4”服務(wù)及其授權(quán)

同上

4 注意:

4.1 啟動

把所有項目的啟動方式修改為:“IIS Express”

4.2 設(shè)定“JwtBearer”令牌(Token)緩沖過期時間為:0

4.2.1 通過“IdentityServer4.AccessTokenValidation”中間件設(shè)定

//通過“IdentityServer4.AccessTokenValidation”中間件,把“JwtBearer”中間件注入.Net7框架內(nèi)置容器中,

builder.Services.AddAuthentication("Bearer")

.AddIdentityServerAuthentication(options =>

{

options.Authority = "https://localhost:44360/";//鑒權(quán)(認(rèn)證)服務(wù)地址

options.RequireHttpsMetadata = false;

//緩沖過期時間,“JwtBearer”令牌(Token)的總有效時間等于該時間加上jwt的過期時間,緩沖過期時間的默認(rèn)值為“5分鐘”,

//當(dāng)前把緩沖過期時間設(shè)定為:0,指定令牌(Token)的總有效時間即為jwt的過期時間。

//注意:

//如果不設(shè)定“JwtBearer”緩沖過期時間設(shè)定為:0,即在IdentityServer4服務(wù)中的時間(120秒之后)過期后,經(jīng)過認(rèn)證特性標(biāo)記的Api控制器方法依然可以獲取其值,因為還“5分鐘”的緩沖過期。

options.JwtValidationClockSkew = TimeSpan.FromSeconds(0);

});

4.2.2 通過“Microsoft.AspNetCore.Authentication.JwtBearer”中間件設(shè)定

//通過“Microsoft.AspNetCore.Authentication.JwtBearer”中間件,把“JwtBearer”中間件注入.Net7框架內(nèi)置容器中,

builder.Services.AddAuthentication("Bearer")

.AddJwtBearer("Bearer", options =>

{

options.Authority = "https://localhost:44360/";

options.RequireHttpsMetadata = false;

options.TokenValidationParameters = new TokenValidationParameters

{

//指示是否對指定令牌(Token)的過期時間進(jìn)行限定,當(dāng)前設(shè)定為:true,即限定。

RequireExpirationTime = true,

//指示是否對指定令牌(Token)的生命周期進(jìn)行自動管理,當(dāng)前設(shè)定為:true,即管理,

//當(dāng)前指定令牌(Token)的生命周期結(jié)束時,程序必須重新生成1個新的指定令牌(Token)才能方法授權(quán)頁面。

//使用當(dāng)前時間與Token的Claims中的NotBefore和Expires對比后,進(jìn)行管理。

ValidateLifetime = true,

//緩沖過期時間,“JwtBearer”令牌(Token)的總有效時間等于該時間加上jwt的過期時間,緩沖過期時間的默認(rèn)值為“5分鐘”,

//當(dāng)前把緩沖過期時間設(shè)定為:0,指定令牌(Token)的總有效時間即為jwt的過期時間。

//注意:

//如果不設(shè)定“JwtBearer”緩沖過期時間設(shè)定為:0,即在IdentityServer4服務(wù)中的時間(120秒之后)過期后,經(jīng)過認(rèn)證特性標(biāo)記的Api控制器方法依然可以獲取其值,因為還“5分鐘”的緩沖過期。

ClockSkew = TimeSpan.FromSeconds(0),

};

});

4.3 內(nèi)置授權(quán)管道中間件必須集成在“IdentityServer4”服務(wù)程序中

內(nèi)置授權(quán)管道中間件必須集成在“IdentityServer4”服務(wù)項目中,否則在使用Postman調(diào)試經(jīng)過認(rèn)證特性標(biāo)記的Api控制器方法時會出現(xiàn):“401Unauthorized”錯誤,如下圖所示。

對以上功能更為具體實(shí)現(xiàn)和注釋見:221204_10IdentityServer4(初識IdentityServer4)。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

本文題目:第11章初識IdentityServer4-創(chuàng)新互聯(lián)
瀏覽地址:http://www.muchs.cn/article46/pcshg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站Google、網(wǎng)站策劃、搜索引擎優(yōu)化、電子商務(wù)、網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)