zoukankan      html  css  js  c++  java
  • 【ASP.NET Core分布式项目实战】(一)IdentityServer4登录中心、oauth密码模式identity server4实现

    本博客根据http://video.jessetalk.cn/my/course/5视频整理

    资料

    OAuth2 流程:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

    博客园晓晨的关于identityServer4的中文文档地址: http://www.cnblogs.com/stulzq/p/8119928.html

    Docker中文文档 https://yeasy.gitbooks.io/docker_practice/content/

    OAuth2.0概念

    OAuth2.0(Open Authorization)是一个开放授权协议;第三方应用不需要接触到用户的账户信息(如用户名密码),通过用户的授权访问用户资源

    OAuth的步骤一般如下:

    1、客户端要求用户给予授权
    2、用户同意给予授权
    3、根据上一步获得的授权,向认证服务器请求令牌(token)
    4、认证服务器对授权进行认证,确认无误后发放令牌
    5、客户端使用令牌向资源服务器请求资源
    6、资源服务器使用令牌向认证服务器确认令牌的正确性,确认无误后提供资源

    该协议的参与者至少包含:

    RO (resource owner): 资源所有者:用户。

    RS (resource server): 资源服务器:数据中心;它存储资源,并处理对资源的访问请求。如:API资源,相册服务器、博客服务器。

    AS (authorization server): 授权服务器

    Client: 第三方应用

    四种模式:

    1、授权码模式(authorization code)
    2、简化模式(implicit)
    3、密码模式(resource owner password credentials)
    4、客户端模式(client credentials)

    接下来我们使用客户端模式来实现一个IdentityServer4授权

    客户端模式(Client Credentials Grant)

    客户端模式(ClientCredentials):经常运用于服务器对服务器中间通讯使用;步骤如下:

    1、客户端直接用自身的信息向授权服务器请求token:

    HTTP请求:

    granttype:授权类型

    scope:授权范围

         POST /token HTTP/1.1
         Host: server.example.com
         Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
         Content-Type: application/x-www-form-urlencoded
    
         grant_type=client_credentials&scope=api001

    2、授权服务器验证信息后返回token

         HTTP/1.1 200 OK
         Content-Type: application/json;charset=UTF-8
         Cache-Control: no-store
         Pragma: no-cache
    
         {
           "access_token":"2YotnFZFEjr1zCsicMWpAA",
           "token_type":"example",
           "expires_in":3600,
           "example_parameter":"example_value"
         }

    下面通过一个快速示例理解;快速示例将通过服务器与服务器直接通过api访问数据;

    授权服务端

    步骤:

    添加Nuget包:IdentityServer4
    
    添加Startup配置
    
    添加Config.cs配置类
    
    更改identity server4配置
    
    添加客户端配置

    第一步:添加Nuget包:IdentityServer4

    首先,新建一个webapi项目  IdentityServerCenter

    dotnet new webapi --name IdentityServerCenter

    我们可以在vscode中使用ctrl+P键来打开命令面板。然后输入nuget按回车,输入identityserver4后按回车来选择版本进行安装

    【注意:重新打开文件夹项目后才能在类中引用IdentityServer4有提示】

    第二步:添加Startup配置

    引用命名空间:

    using IdentityServer4;

    添加IdentityServer依赖注入

    services.AddIdentityServer()
        .AddDeveloperSigningCredential();//添加开发人员签名凭据
    使用IdentityServer
    app.UseIdentityServer();//使用IdentityServer

    我们可以在Program.cs将当前api的地址设置成http://localhost:5000

    第三步:添加Config.cs配置类

     我们接下来添加一个Config.cs类,这个类是用来初始化IdentityServer的

    using System.Collections;
    using System.Collections.Generic;
    using IdentityServer4;
    using IdentityServer4.Models;
    
    namespace IdentityServerCenter
    {
        public class Config
        {
            //所有可以访问的Resource
            public static IEnumerable<ApiResource> GetResources()
            {
                return new List<ApiResource>
                {
                    new ApiResource("api","My Api")
                };
            }
    
            //客户端
            public static IEnumerable<Client> GetClients()
            {
                return new List<Client>
                {
                    new Client()
                    {
                        ClientId="client",
                        AllowedGrantTypes= GrantTypes.ClientCredentials,//模式:最简单的模式
                        ClientSecrets={//私钥
                            new Secret("secret".Sha256())
                        },
                        AllowedScopes={//可以访问的Resource
                            "api"
                        }
                    }
                };
            }
    
        }
    }
    View Code

    第四步:更改identity server4配置

    services.AddIdentityServer()
        .AddDeveloperSigningCredential()//添加开发人员签名凭据
        .AddInMemoryApiResources(Config.GetResources());//添加内存apiresource

    第五步:添加客户端配置

    services.AddIdentityServer()
        .AddDeveloperSigningCredential()//添加开发人员签名凭据
        .AddInMemoryApiResources(Config.GetResources())//添加内存apiresource
        .AddInMemoryClients(Config.GetClients());//添加内存client

    这是后我们执行dotnet run通过http://localhost:5000/.well-known/openid-configuration访问 ;可以看到是一个restful的api;

     

    客户端集成IdentityServer

    新建一个新的webapi,命名为ClientCredentialApi

    dotnet new webapi --name ClientCredentialApi

    给控制器添加引用Microsoft.AspNetCore.Authorization并添加  [Authorize]  标签

    添加中间件IdentityServer4.AccessTokenValidation 包引用

     

    配置api的地址 http://localhost:5001

     

    添加授权DI注入

    services.AddAuthentication("Bearer")//添加授权模式
        .AddIdentityServerAuthentication(Options=>{
            Options.Authority="http://localhost:5000";//授权服务器地址
            Options.RequireHttpsMetadata=false;//是否是https
            Options.ApiName="api";
       });
    使用授权中间件
    app.UseAuthentication();//使用授权中间件

    这时候执行 dotnet run进行访问http://localhost:5001/api/values

    这时候我们运行之前的IdentityServerCenter通过http://localhost:5000/.well-known/openid-configuration访问 ,来拿到获取token的地址  http://localhost:5000/connect/token

    我们接下来使用postman来获取一下token,请求参数

    client_id、client_secret、grant_type

    这样我们拿到token后,再去访问ClientCredentialApi(成功)

    控制台获取token

    新建一个控制台ThirdPartyDemo

    dotnet new console --name ThirdPartyDemo

    添加添加nuget引用包 IdentityModel

    using System;
    using System.Net.Http;
    using IdentityModel.Client;
    
    namespace ThirdPartyDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                var dico = DiscoveryClient.GetAsync("http://localhost:5000").Result;
    
                //token
                var tokenClient = new TokenClient(dico.TokenEndpoint, "client", "secret");
                var tokenResponse = tokenClient.RequestClientCredentialsAsync("api").Result;
                if (tokenResponse.IsError)
                {
                    Console.WriteLine(tokenResponse.Error);
                    return;
    
                }
    
                Console.WriteLine(tokenResponse.Json);
                Console.WriteLine("
    
    ");
    
    
                var httpClient = new HttpClient();
                httpClient.SetBearerToken(tokenResponse.AccessToken);
    
                var response = httpClient.GetAsync("http://localhost:5001/api/values").Result;
                if (!response.IsSuccessStatusCode)
                {
                    Console.WriteLine(response.Content.ReadAsStringAsync().Result);
                }
    
                Console.ReadLine();
            }
        }
    }
    View Code

    DiscoveryClient类:IdentityModel提供给我们通过基础地址(如:http://localhost:5000)就可以访问令牌服务端;当然可以根据上面的restful api里面的url自行构建;上面就是通过基础地址,获取一个TokenClient;(对应restful的url:token_endpoint   "http://localhost:5000/connect/token")

    RequestClientCredentialsAsync方法:请求令牌;

    获取令牌后,就可以通过构建http请求访问API接口;这里使用HttpClient构建请求,获取内容;

    运行效果:

    oauth密码模式identity server4实现

    1、Config.cs添加用户的配置

    2、添加client的配置

    3、修改Startup.cs

    Config.cs添加用户的配置

    添加测试用户,并给其用户名密码(其他Claim);TestUser是IdentityServer给我们的测试抽象用户类;实际可自行定义

    TestUser类型表示一个测试用户及其身份信息。让我们向配置类(如果你有严格按照顺序进行演练,那么配置类应该在 QuickstartIdentityServer 项目的 Config.cs 文件中)中添加以下代码以创建一对用户:

    首先添加以下语句 到Config.cs文件中:

            //测试用户
            public static List<TestUser> GetTestUsers()
            {
                return new List<TestUser>{
                    new TestUser{
                        SubjectId="1",
                        Username="wyt",
                        Password="123456"
                    }
                };
            }

    添加client的配置

    添加一个客户端

    修改Startup.cs

    这里AddTestUser会给授权服务端增加各类支持用户(RO)的密码支持

     

    我们接下来使用postman来获取一下账号密码模式token,请求参数【注意:这里必须要使用x-www-form-urlencoded的请求方式,否则无法获取token】

    client_id、client_secret、grant_type、username、password

    完成~~~

    控制台请求获取token

    新建一个控制台PwdClient

    dotnet new console --name PwdClient

     添加添加nuget引用包 IdentityModel

    using System;
    using System.Net.Http;
    using IdentityModel.Client;
    
    namespace PwdClient
    {
        class Program
        {
            static void Main(string[] args)
            {
                var dico = DiscoveryClient.GetAsync("http://localhost:5000").Result;
    
                //token
                var tokenClient = new TokenClient(dico.TokenEndpoint, "pwdClient", "secret");
                var tokenResponse = tokenClient.RequestResourceOwnerPasswordAsync("wyt","123456").Result;
                if (tokenResponse.IsError)
                {
                    Console.WriteLine(tokenResponse.Error);
                    return;
    
                }
    
                Console.WriteLine(tokenResponse.Json);
                Console.WriteLine("
    
    ");
    
    
                var httpClient = new HttpClient();
                httpClient.SetBearerToken(tokenResponse.AccessToken);
    
                var response = httpClient.GetAsync("http://localhost:5001/api/values").Result;
                if (!response.IsSuccessStatusCode)
                {
                    Console.WriteLine(response.Content.ReadAsStringAsync().Result);
                }
    
                Console.ReadLine();
            }
        }
    }
    View Code

    运行效果:

     

    如果信任的第三方,不想加入密码,可以在授权服务的Config.cs中Client添加设置RequireClientSecret=false即可

  • 相关阅读:
    尝试用微博记录 SQL Server 2012开发者训练营笔记
    Contact Manager Web API 示例[4] 异常处理(Exception Handling)
    使用IAPIExplorer列举ASP.NET Web API
    从 WebAPI Beta 更新到WebAPI RC
    Tracing in ASP.NET Web API
    一个基于asp.net2.0空间的webproxy程序:ASProxy
    微软发布平板电脑 – Surface
    Big Data, Hadoop and StreamInsight™
    REST 入门介绍
    通过企业分布式缓存共享运行时数据
  • 原文地址:https://www.cnblogs.com/wyt007/p/8284482.html
Copyright © 2011-2022 走看看