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