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.Web",//客戶端惟一標識
ClientSecrets = new [] { new Secret("MengLin123456".Sha256()) },//客戶端密碼,進行了加密
AllowedGrantTypes = GrantTypes.ClientCredentials,//Grant類型
AllowedScopes = new [] { "UserApi" },//允許訪問的資源
Claims= new List<Claim>() { new Claim(IdentityModel.JwtClaimTypes.Role,"Admin"), new Claim(IdentityModel.JwtClaimTypes.NickName,"豆豆爸爸"), new Claim("EMail","menglin2010@126.com") } } }; } }
二.客戶端調用
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的郵箱是menglin2010@126.com
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是menglin2010@126.com,是網易郵箱(5.1)
在客戶端調用的時候,自定義授權策略要求Claim Email是qq郵箱,條件不滿足(5.2),盡管訪問http://localhost:9527/TestIds4/IndexPolicyQQEMail帶上了token,但是不滿足授權,所以報403錯誤拒絕訪問