• IdentityServer4专题之五:OpenID Connect及其Client Credentials流程模式


    1.基于概念

    OAuth2.0与身份认证协议的角色映射

     

    OpenID Connect 这个协议是2014颁发的,基于OAuth2.0,在这个协议中,ID Token会和Access Token一起发回客户端应用,它还提供了一个UserInfo这个端点,通过此端点可以获取用户信息,还提供了一级标识身份的scopes和claims(profile、email、address、phone)

     

    这个协议定义了三个流程:

     

    Identity Server4.0的结构图

    2.三种流程模式

    IdentityServer上:

    在startup.cs页面中ConfiureServices页面中,应将json config 方式改为code config方式。即按如下方式切换注释代码

    // in-memory, code config

                builder.AddInMemoryIdentityResources(Config.GetIdentityResources());

                builder.AddInMemoryApiResources(Config.GetApis());

                builder.AddInMemoryClients(Config.GetClients());

      // in-memory, json config

                //builder.AddInMemoryIdentityResources(Configuration.GetSection("IdentityResources"));

     //builder.AddInMemoryApiResources(Configuration.GetSection("ApiResources"));

    //builder.AddInMemoryClients(Configuration.GetSection("clients"));

     

    public static class Config

        {

            public static IEnumerable<IdentityResource> GetIdentityResources()

            {

                return new IdentityResource[]

                {

                    new IdentityResources.OpenId(),

                    new IdentityResources.Profile(),

                };

            }

            public static IEnumerable<ApiResource> GetApis()

            {

                return new ApiResource[]

                {

                    new ApiResource("api1", "My API #1")

                };

            }

            public static IEnumerable<Client> GetClients()

            {

                return new[]

                {

                    // client credentials flow client

                    new Client

                    {

                        ClientId = "console client",

                        ClientName = "Client Credentials Client",

                        AllowedGrantTypes = GrantTypes.ClientCredentials,

                        ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },

                        AllowedScopes = {"api1" }

                    }              

                };

            }

       }

     

    客户端控制台程序代码:

    static async Task Main(string[] args)

            {

                //Discovery endpoint

                Console.WriteLine("Hello World!");

                var client = new HttpClient();

                var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");

                if(disco.IsError)

                {

                    Console.WriteLine(disco.Error);

                    return;

                }

                //Request access token,客户端必须带有:ClientCredentials

                var tokenResponse =await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest {

                    Address = disco.TokenEndpoint,

                    ClientId = "console client",

                    ClientSecret = "511536EF-F270-4058-80CA-1C89C192F69A",

                    Scope= "api1"

                });

                if (tokenResponse.IsError)

                {

                    Console.WriteLine(tokenResponse.Error);

                    return;

                }

                var apiClient = new HttpClient();

                apiClient.SetBearerToken(tokenResponse.AccessToken);

                var response = await apiClient.GetAsync("http://localhost:5002/api/values");

                if (!response.IsSuccessStatusCode)

                {

                    Console.WriteLine(response.StatusCode);

                }

                else

                {

                    var content = await response.Content.ReadAsStringAsync();

                    Console.WriteLine(content);

                 }

    asp.net core api资源应用:

    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)

            {         

                //使用IdentityServer认证和授权

                services.AddMvcCore().AddAuthorization().AddJsonFormatters();

                services.AddAuthentication("Bearer")

                    .AddJwtBearer("Bearer", options =>

                    {

                        options.Authority = "http://localhost:5000";

                        options.RequireHttpsMetadata = false;

                        options.Audience = "api1";

                    });          

              }

               public void Configure(IApplicationBuilder app, IHostingEnvironment env)

               {   //使用identityserver

                app.UseAuthentication();

                app.UseMvc();

               }

      }

     

     

     

    [Route("api/[controller]")]

        [Authorize]

        [ApiController]

        public class ValuesController : ControllerBase

        {

            // GET api/values

            [HttpGet]

            public ActionResult<IEnumerable<string>> Get()

            {

                return new string[] { "value1", "value2","value3"};

            }

    总结:Client Credentials这种方式,客户端应用不代表用户,客户端应用本身就相当于是资源所有者;通常用于机器对机器的通信;客户端也需要身份认证。

    可采用工具软件监控客户端与服务端的通信:

    将获取的access token放到网站https://jwt.io/,进行解码,即可以看到token中包含的许多用用信息。

    见贤思齐,见不贤而自省
  • 相关阅读:
    python数据采集与多线程效率分析
    Memcache使用基础
    《大规模 web服务开发》笔记
    画了一张PHPCMSV9的运行流程思维导图
    MySQL的正则表达式
    linux patch 格式与说明(收录)
    Memcached笔记之分布式算法
    bzoj 2120 带修改莫队
    bzoj 2073 暴力
    bzoj 1814 Ural 1519 Formula 1 插头DP
  • 原文地址:https://www.cnblogs.com/Sweepingmonk/p/10868722.html
Copyright © 2020-2023  润新知