• ASP.NET Core分布式项目实战(oauth密码模式identity server4实现)--学习笔记


    任务12:oauth密码模式identity server4实现

    密码模式比客户端模式更加严格,需要第三方输入用户名和密码之后才可以访问 API

    在 IdentityServerCenter 的 Config 中引入测试命名空间

    using IdentityServer4.Test;
    

    并添加一个获取 TestUser 的方法

    public static List<TestUser> GetTestUsers()
    {
        return new List<TestUser>
        {
            new TestUser
            {
                SubjectId = "1",
                Username = "mingsonzheng",
                Password = "123456"
            }
        };
    }
    

    正式环境的话从数据库读取

    client 列表中复制添加一个 client,修改 ClientId 和 AllowedGrantTypes

    new Client()
    {
        ClientId = "pwdclient",
        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
        ClientSecrets = 
        {
            new Secret("secret".Sha256())
        },
        AllowedScopes = {"api"},
    }
    

    在 Startup 中 AddTestUsers

    services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryApiResources(Config.GetResource())
            .AddInMemoryClients(Config.GetClients())
            .AddTestUsers(Config.GetTestUsers());
    

    启动 IdentityServerCenter 与 ClientCredentialApi

    获取 access_token

    在 config 中可以通过修改配置 RequireClientSecret,使得调用接口不需要传参 client_secret

    new Client()
    {
        ClientId = "pwdClient",
        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
        ClientSecrets = 
        {
            new Secret("secret".Sha256())
        },
        AllowedScopes = {"api"},
        RequireClientSecret = false,
    }
    

    新建控制台程序

    dotnet new console --name PwdClient
    

    添加 Nuget 包:IdentityModel

    添加之后还原

    dotnet restore
    

    拷贝一份 ThirdPartyDemo 的 Program 过来修改

    using System;
    using System.Net.Http;
    using System.Threading.Tasks;
    using IdentityModel.Client;
    using Newtonsoft.Json.Linq;
    
    namespace PwdClient
    {
        class Program
        {
            static async Task Main(string[] args)
            {
                // discover endpoints from metadata
                var client = new HttpClient();
                var disco = client.GetDiscoveryDocumentAsync("http://localhost:5000").Result;
                if (disco.IsError)
                {
                    Console.WriteLine(disco.Error);
                    return;
                }
    
                // // request token
                // var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
                // {
                //     Address = disco.TokenEndpoint,
    
                //     ClientId = "client",
                //     ClientSecret = "secret",
                //     Scope = "api"
                // });
    
                // request token
                var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
                {
                    Address = disco.TokenEndpoint,
    
                    ClientId = "pwdClient",
                    ClientSecret = "secret",
                    Scope = "api",
    
                    UserName = "mingsonzheng",
                    Password = "123456",
                });
    
                if (tokenResponse.IsError)
                {
                    Console.WriteLine(tokenResponse.Error);
                    return;
                }
    
                Console.WriteLine(tokenResponse.Json);
    
                // call api
                var client2 = new HttpClient();
                client2.SetBearerToken(tokenResponse.AccessToken);
    
                var response = await client2.GetAsync("http://localhost:5001/weatherforecast");
                if (!response.IsSuccessStatusCode)
                {
                    Console.WriteLine(response.StatusCode);
                }
                else
                {
                    var content = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(JArray.Parse(content));
                }
            }
        }
    }
    

    先启动 IdentityServerCenter,ClientCredentialApi

    再启动 PwdClient,输出如下:

    {
      "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImZFd0d5VGQtY2FkaE9Oamp6ajc5THciLCJ0eXAiOiJhdCtqd3QifQ.eyJuYmYiOjE1ODY0NTA4ODQsImV4cCI6MTU4NjQ1NDQ4NCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjoiYXBpIiwiY2xpZW50X2lkIjoicHdkQ2xpZW50Iiwic3ViIjoiMSIsImF1dGhfdGltZSI6MTU4NjQ1MDg4NCwiaWRwIjoibG9jYWwiLCJzY29wZSI6WyJhcGkiXSwiYW1yIjpbInB3ZCJdfQ.xAndZZqCfNGblZmyxLEmWYHFmy26g75kk7cOCkppmWWbmf3ISQVM66hTiGfgpC2xntorRDBPhDtVU0hmmmoEukycTIbeR1jdg8hYyKF2lcuFzTldOIs5ogtp84Gk0GcKkv0Ecurz5onAsZAMLjV_f2bMr8k2DPOA9062L5ULxqWuk00jK3S1f8FPACWGqO87MUIimt4YGxySggdzr2INwmqBOb8HZcA3gCoz9vxf0i_RNBvq_9D7YnfiGIAIevR_MAymDGoK-1KzENcmyS15yFnDClUjcVgFBAUUuNEiB4106w9Uft5Tao1EUxI0_oy7_HulDpSY0Cs4RCyL5mlU4Q",
      "expires_in": 3600,
      "token_type": "Bearer",
      "scope": "api"
    }
    [
      {
        "date": "2020-04-11T00:48:04.3089512+08:00",
        "temperatureC": 22,
        "temperatureF": 71,
        "summary": "Warm"
      },
      {
        "date": "2020-04-12T00:48:04.3089617+08:00",
        "temperatureC": 24,
        "temperatureF": 75,
        "summary": "Chilly"
      },
      {
        "date": "2020-04-13T00:48:04.308962+08:00",
        "temperatureC": 37,
        "temperatureF": 98,
        "summary": "Cool"
      },
      {
        "date": "2020-04-14T00:48:04.3089622+08:00",
        "temperatureC": -3,
        "temperatureF": 27,
        "summary": "Mild"
      },
      {
        "date": "2020-04-15T00:48:04.3089624+08:00",
        "temperatureC": 46,
        "temperatureF": 114,
        "summary": "Sweltering"
      }
    ]
    

    课程链接

    http://video.jessetalk.cn/course/explore

    知识共享许可协议

    本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

    欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

    如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。

  • 相关阅读:
    Spring Boot
    Spring Boot – Jetty配置
    如何使ESLint在Visual Studio 2019和2017中工作: 2019 v16和2017> = v15.8
    CentOS 7 安装 Nginx
    HTTPS-使用Certbot自动配置Let’s Encrypt证书
    centos7升级内核到最新版本
    [C#.net]Connection Timeout和Command Timeout
    Redis中切换db
    Redis 模糊查询删除操作
    [Abp vNext 源码分析]
  • 原文地址:https://www.cnblogs.com/MingsonZheng/p/12670821.html
Copyright © 2020-2023  润新知