【ASP.NET Core分佈式項目實戰】(一)IdentityServer4登陸中心、oauth密碼模式identity server4實現

 

本博客根據http://video.jessetalk.cn/my/course/5視頻整理html

資料

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

博客園曉晨的關於identityServer4的中文文檔地址: http://www.cnblogs.com/stulzq/p/8119928.htmlweb

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

OAuth2.0概念

OAuth2.0(Open Authorization)是一個開放受權協議;第三方應用不須要接觸到用戶的帳戶信息(如用戶名密碼),經過用戶的受權訪問用戶資源json

OAuth的步驟通常以下:api

一、客戶端要求用戶給予受權
二、用戶贊成給予受權
三、根據上一步得到的受權,向認證服務器請求令牌(token)
四、認證服務器對受權進行認證,確認無誤後發放令牌
五、客戶端使用令牌向資源服務器請求資源
六、資源服務器使用令牌向認證服務器確認令牌的正確性,確認無誤後提供資源服務器

該協議的參與者至少包含:restful

RO (resource owner): 資源全部者:用戶。app

RS (resource server): 資源服務器:數據中心;它存儲資源,並處理對資源的訪問請求。如:API資源,相冊服務器、博客服務器。ide

AS (authorization server): 受權服務器

Client: 第三方應用

 

四種模式:

一、受權碼模式(authorization code)
二、簡化模式(implicit)
三、密碼模式(resource owner password credentials)
四、客戶端模式(client credentials)

接下來咱們使用客戶端模式來實現一個IdentityServer4受權

客戶端模式(Client Credentials Grant)

客戶端模式(ClientCredentials):常常運用於服務器對服務器中間通信使用;步驟以下:

一、客戶端直接用自身的信息向受權服務器請求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

二、受權服務器驗證信息後返回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實現

一、Config.cs添加用戶的配置

二、添加client的配置

三、修改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便可

相關文章
相關標籤/搜索