• 【ASP.NET Core 3.1】【鉴权,授权】OAuth2.0四种授权模式--客户端模式


    一、鉴权中心
    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.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")
                    }
                }
            };
        }
    }

    二、客户端调用

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

  • 相关阅读:
    一、Javadoc文档标记
    0-写在java系列文章之前
    Tomcat全攻略
    linux使用普通账户时,无法登录,提示“-bash: fork: retry: Resource temporarily unavailable”
    在Linux下安装和使用MySQL
    linux下修改jdk环境变量的方法
    linux下卸载系统自带或者非自带的jdk
    linux中 /etc/profile的作用
    每天一个linux命令:tar命令-jia2
    如何使用蓝湖设计稿同时适配PC及移动端
  • 原文地址:https://www.cnblogs.com/menglin2010/p/13797701.html
Copyright © 2020-2023  润新知