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错误拒绝访问