public void ConfigureServices(IServiceCollection services)
{
//services.AddControllers();
services.AddControllersWithViews();
#region 客戶端模式
{
services.AddIdentityServer()//怎麼處理
.AddDeveloperSigningCredential()
.AddInMemoryClients(ClientInitConfig.GetClients())//InMemory 內存模式
.AddInMemoryApiResources(ClientInitConfig.GetApiResources());//能訪問啥資源
}
#endregion
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
#region 添加IdentityServer中間件
app.UseIdentityServer();
#endregion
//授權
app.UseAuthorization();
}
1.4、客戶端模式配置--ClientInitConfig
/// <summary>
/// 客戶端模式
/// </summary>
public class ClientInitConfig
{
/// <summary>
/// 定義ApiResource
/// 這裏的資源(Resources)指的就是管理的API
/// </summary>
/// <returns>多個ApiResource</returns>
public static IEnumerable<ApiResource> GetApiResources()
{
return new[]
{
new ApiResource("UserApi", "用戶獲取API")
};
}
/// <summary>
/// 定義驗證條件的Client
/// </summary>
/// <returns></returns>
public static IEnumerable<Client> GetClients()
{
return new[]
{
new Client
{
ClientId = "MengLin.Shopping.AuthenticationCenterIds4",//客戶端惟一標識
ClientSecrets = new [] { new Secret("MengLin123456".Sha256()) },//客戶端密碼,進行了加密
AllowedGrantTypes = GrantTypes.ClientCredentials,
AllowedScopes = new [] { "UserApi" },//允許訪問的資源
Claims= new List<Claim>()
{
new Claim(IdentityModel.JwtClaimTypes.Role,"Admin"),
new Claim(IdentityModel.JwtClaimTypes.NickName,"豆豆爸爸"),
new Claim("EMail","[email protected]")
}
}
};
}
}
二、客戶端調用
public void ConfigureServices(IServiceCollection services)
{
#region IdentityServer4 模式
{
#region 客戶端模式
//鑑權
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
//ids4的地址,目的: 獲取公鑰,因爲獲取獲取了公鑰才能解密
options.Authority = "http://localhost:10010";
options.ApiName = "UserApi";
options.RequireHttpsMetadata = false;
});
//自定義授權--必須包含Claim client_role & 必須是Admin
services.AddAuthorization(options =>
{
options.AddPolicy("AdminPolicy",
policyBuilder => policyBuilder
.RequireAssertion(context =>
context.User.HasClaim(c => c.Type == "client_role")
&& context.User.Claims.First(c => c.Type.Equals("client_role")).Value.Equals("Admin")));
});
//自定義授權--必須包含Claim client_EMail & 必須qq結尾
services.AddAuthorization(options =>
{
options.AddPolicy("EMailPolicy",
policyBuilder => policyBuilder
.RequireAssertion(context =>
context.User.HasClaim(c => c.Type == "client_EMail")
&& context.User.Claims.First(c => c.Type.Equals("client_EMail")).Value.EndsWith("@qq.com")));
});
#endregion
}
#endregion
}
三、控制器
public class TestIds4Controller : Controller
{
/// <summary>
/// 基本授權
/// </summary>
/// <returns></returns>
[Authorize]
public IActionResult Index()
{
foreach (var item in base.HttpContext.User.Identities.First().Claims)
{
Console.WriteLine($"{item.Type}:{item.Value}");
}
return View();
}
/// <summary>
/// 策略授權--自定義授權--必須包含Claim client_role & 必須是Admin
/// </summary>
/// <returns></returns>
[Authorize(Policy = "AdminPolicy")]
public IActionResult IndexPolicy()
{
return View();
}
/// <summary>
/// 策略授權--自定義授權--必須包含Claim client_EMail & 必須qq結尾
/// </summary>
/// <returns></returns>
[Authorize(Policy = "EMailPolicy")]
public IActionResult IndexPolicyQQEMail()
{
return View();
}
}
四、基本授權測試
4.1、命令行啓動 dotnet MengLin.Shopping.Web.dll –-urls=http://*:9527,訪問http://localhost:9527/TestIds4/Index,報401,未授權
4.2、命令行啓動鑑權中心dotnet MengLin.Shopping.AuthenticationCenterIds4.dll –-urls=http://*:10010,訪問http://localhost:10010/connect/token,獲取token後,帶上token再訪問http://localhost:9527/TestIds4/Index,響應200不再是401
五、策略授權測試
5.1、在鑑權中心頒發token的時候,指定了Claim的角色是Admin,且指定了Claim的郵箱是[email protected]
5.2、在客戶端調用的時候,指定了自定義授權策略,必須包含Claim是角色的,且值必須是Admin
5.3、訪問http://localhost:9527/TestIds4/IndexPolicy是可以訪問的,因爲鑑權中心頒發token的時候Claim Role是Admin(5.1)
在客戶端調用的時候,自定義授權策略要求有Claim Role且值必須是Admin(5.2),條件滿足,允許訪問
5.4、在客戶端調用的時候,指定了自定義授權策略,必須包含Claim是client_Email的,且值必須是qq郵箱
5.5、訪問http://localhost:9527/TestIds4/IndexPolicyQQEMail是不能訪問的,因爲鑑權中心頒發token的時候Claim Email是[email protected],是網易郵箱(5.1)
在客戶端調用的時候,自定義授權策略要求Claim Email是qq郵箱,條件不滿足(5.2),儘管訪問http://localhost:9527/TestIds4/IndexPolicyQQEMail帶上了token,但是不滿足授權,所以報403錯誤拒絕訪問