一.鉴权中心
1.1.Nuget引入IdentityServer4(3.1.3)
我开始引入的是IdentityServer4(4.1.4),但是访问:http://localhost:10010/connect/token总是报{ "error": "invalid_request"},最后我降低版本引入了IdentityServer4(3.1.3)才好,有谁知道原因的请留言告诉我下
 1.2.Startup--ConfigureServices配置-以什么方式颁发Token
public void ConfigureServices(IServiceCollection services)
{
    //services.AddControllers();
    services.AddControllersWithViews();

    #region 客户端模式
    {
        services.AddIdentityServer()//怎么处理
                .AddDeveloperSigningCredential()
                .AddInMemoryClients(ClientInitConfig.GetClients())//InMemory 内存模式
                .AddInMemoryApiResources(ClientInitConfig.GetApiResources());//能访问啥资源
    }
    #endregion
}
 1.3.Startup--Configure配置-添加IdentityServer中间件
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")
                }
            }
        };
    }
}

 二.客户端调用

2.1.Startup-ConfigureServices配置
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错误拒绝访问

 

总结:我自己做的教育网站,需要腾讯课堂授权才能访问,在腾讯课堂得备案一下,腾讯课堂给我发一个ClientId、ClinetSecret针对客户端的,不是针对人的