【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("\n\n");


            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("\n\n");


            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即可

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM