ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

根据 scope 策略设置受保护api访问权限

2022-01-22 18:33:33  阅读:240  来源: 互联网

标签:new client token api credentials scope 权限 Config public


1 添加 apiscope

2 添加 apiresource

添加api名为“client_credentials_apis”的apiresource,并把作用域“client_credentials_apis.IdentityUserController.scope”和“client_credentials_apis.WeatherForecastController.scope”添加到该apiresource中

 

 

3 在 ids 添加客户端

添加客户端,添加客户端密钥,设置授权类型(比如 客户端凭证方式),并至少设置一个 自定义的 apiscope(如添加 client_credentials_apis.WeatherForecastController.scope);token类型默认为 jwt。

4 客户端获取 token并使用 该token访问api资源

 

 接下来给客户端添加  client_credentials_apis.IdentityUserController.scope ,重新访问结果如下:

 

 再给客户端添加 client_credentials_apis.WeatherForecastController.scope,重新访问结果如下

客户端添加作用域如下图:

 

 

 5 相关代码

5.1 api资源端代码如下:

配置如下:

namespace Resources_Https
{
    public class Config
    {
        /// <summary>
        /// identity server 地址
        /// </summary>
        public const string IdentityServerUri = "https://localhost:44310";

        /// <summary>
        /// reference tokens 的 clientId
        /// </summary>
        public const string ApiName = "client_credentials_apis";

        /// <summary>
        /// reference tokens 的 clientSecret
        /// </summary>
        public const string ApiSecret = "123456";
    }
}

startup.cs 代码如下:

using IdentityModel.AspNetCore.OAuth2Introspection;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;

namespace Resources_Https
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // nuget 安装 Microsoft.AspNetCore.Authentication.JwtBearer
            // jwt tokens
            services.AddAuthentication(OAuth2IntrospectionDefaults.AuthenticationScheme)
            .AddJwtBearer("Bearer", options =>
            {
                options.Authority = Config.IdentityServerUri;

                // 设置 https
                options.RequireHttpsMetadata = true;

                options.Audience = Config.ApiName;
            });

            //// reference tokens
            //services.AddAuthentication("Introspection")
            //.AddOAuth2Introspection("Introspection", options =>
            //{
            //    options.Authority = Config.IdentityServerUri;

            //    // this maps to the API resource name and secret
            //    options.ClientId = Config.ApiName; // api 名
            //    options.ClientSecret = Config.ApiSecret; // 配置的 api 秘钥
            //});

            // 策略授权
            services.AddAuthorization(options =>
            {
                // client allowedscope 包含 client_credentials_apis.WeatherForecastController.scope 才能访问
                options.AddPolicy("WeatherForecastController",
                    policy => policy.RequireScope("client_credentials_apis.WeatherForecastController.scope")
                    );

                options.AddPolicy("IdentityUserController",
                    policy => policy.RequireScope("client_credentials_apis.IdentityUserController.scope")
                    );
            });

            services.AddControllers();

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "Resources_Https", Version = "v1" });
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Resources_Https v1"));
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

TestController代码:

    [ApiController]
    [Route("[controller]/[action]")]
    [Authorize]
    public class TestController : ControllerBase
    {
        public IActionResult Ping()
        {
            return new JsonResult(new { code = 0, msg = "TestController pong" });
        }
    }

IdentityUserController 代码:

    [ApiController]
    [Route("[controller]/[action]")]
    [Authorize(Policy = "IdentityUserController")]
    public class IdentityUserController : ControllerBase
    {
        [HttpGet]
        public IActionResult Ping()
        {
            return new JsonResult(new { code = 0, msg = "IdentityUserController pong" });
        }

        [HttpGet]
        public IActionResult GetClaims()
        {
            var claims = User.Claims.ToList();

            var id = User.Identity as ClaimsIdentity;
            var claim = id.FindFirst(JwtClaimTypes.Subject);


            return new JsonResult(claims);
        }
    }

WeatherForecastController 代码:

    [ApiController]
    [Route("[controller]/[action]")]
    [Authorize(Policy = "WeatherForecastController")]
    public class WeatherForecastController : ControllerBase
    {
        [HttpGet]
        public IActionResult Ping()
        {
            return new JsonResult(new { code = 0, msg = "WeatherForecastController pong" });
        }
    }

5.2 客户端代码

配置代码:

    public class Config
    {
        /// <summary>
        /// identity server 地址
        /// </summary>
        public const string IdentityServerUri = "https://localhost:44310";

        /// <summary>
        /// 受保护的api地址
        /// </summary>
        public const string ResourceUri = "https://localhost:6001";

        public const string ClientId = "ClientCredentials_1_ClientId";

        public const string ClientSecret = "511536EF-F270-4058-80CA-1C89C192F69A";

        public const string GrantType = "client_credentials";
    }

获取token和访问资源代码:

    /// <summary>
    /// 使用 HttpClient 通过客户端凭证方式获取token与资源
    /// 适用场景:一般用于服务端应用与服务端应用交互
    /// 请求token链接格式:{idsServer}/connect/token?client_id={}&client_secret={}&grant_type=client_credentials
    /// </summary>
    public class HttpClient_ClientCredentials
    {
        public static void Run()
        {
            // 先获取 access token
            var token_res = string.Empty;
            string postData = $"client_id={Config.ClientId}&client_secret={Config.ClientSecret}&grant_type={Config.GrantType}";
            using (var httpClient = new HttpClient())
            {
                using (HttpContent httpContent = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes(postData))))
                {
                    httpContent.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
                    token_res = httpClient.PostAsync($"{Config.IdentityServerUri}/connect/token", httpContent).Result.Content.ReadAsStringAsync().Result;
                }
            }

            // 使用 token 访问资源
            if (!string.IsNullOrEmpty(token_res)){
                using(HttpClient getClient = new HttpClient())
                {
                    getClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + JObject.Parse(token_res)["access_token"].ToString());
                    // 有token就能访问
                    var apiRes1 = getClient.GetStringAsync($"{Config.ResourceUri}/Test/Ping").Result;
                    // 有token就能访问且 client allowedscope 包含 client_credentials_apis.IdentityUserController.scope 才能访问
                    var apiRes2 = getClient.GetStringAsync($"{Config.ResourceUri}/IdentityUser/Ping").Result;
                    // 有token就能访问且 client allowedscope 包含 client_credentials_apis.WeatherForecastController.scope 才能访问
                    var res_res3 = getClient.GetStringAsync($"{Config.ResourceUri}/WeatherForecast/Ping").Result;
                }
            }
        }
    }

 

参考资源

https://blog.csdn.net/ma_jiang/article/details/107120049

标签:new,client,token,api,credentials,scope,权限,Config,public
来源: https://www.cnblogs.com/tomorrow0/p/15834706.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有