1. 程式人生 > >IdentityServer4(7)- 使用客戶端認證控制API訪問(客戶端授權模式)

IdentityServer4(7)- 使用客戶端認證控制API訪問(客戶端授權模式)

一.前言

目前官方的文件和Demo以及一些相關元件全部是.net core 1.1的,應該是因為目前IdentityServer4目前最新版本只是2.0.0 rc1的原因,官方文件和Demo還沒來更新。我準備使用的是.net core 2.0 所支援的IdentityServer4 2.0.0,官方文件及Demo只能參考,因為在asp.net core 2.0及IdentityServer4 2.0版本中一些介面做了調整,有些寫法和原來不一樣。本文是根據官方QuickStart1(官方QuickStart演示專案的目前只支援.net core 1.1,QuickStart1是第一個QuickStart)寫出的demo。

第一次接觸IdentityServer4是在ABP的asp.net zero專案中,感覺IdentityServer4挺方便的,便有了系統性的學一下IdentityServer4的想法,這是我寫IdentityServer4系列文章的原因。

二.使用客戶端認證保護API

此示例介紹了使用IdentityServer保護API的最基本場景。

在這種情況下,我們將定義一個API和要訪問它的客戶端。 客戶端將在IdentityServer上請求訪問令牌,並使用它來訪問API。

三.準備

建立一個名為QuickstartIdentityServer的ASP.NET Core Web 空專案(asp.net core 2.0),埠5000
建立一個名為Api

的ASP.NET Core Web Api 專案(asp.net core 2.0),埠5001
建立一個名為Client的控制檯專案(.net core 2.0)

四.定義API

QuickstartIdentityServer專案中新增一個Config.cs檔案:

// scopes define the API resources in your system
public static IEnumerable<ApiResource> GetApiResources()
{
    return new List<ApiResource>
    {
        new ApiResource("api1", "My API")
    };
}

五.定義客戶端

對於這種情況,客戶端將不具有互動式使用者,並將使用IdentityServer使用所謂的客戶機密碼進行身份驗證。 將以下程式碼新增到Config.cs檔案中:

// client want to access resources (aka scopes)
public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        new Client
        {
            ClientId = "client",
            // 沒有互動性使用者,使用 clientid/secret 實現認證。
            AllowedGrantTypes = GrantTypes.ClientCredentials,
            // 用於認證的密碼
            ClientSecrets = 
            {
                new Secret("secret".Sha256())
            },
            // 客戶端有權訪問的範圍(Scopes)
            AllowedScopes = { "api1" }
        }
    };
}

六.配置 IdentityServer

要配置IdentityServer以使用Scope和客戶端定義,您需要向ConfigureServices方法新增程式碼。

Startup.cs

// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
    // 使用記憶體儲存的金鑰,客戶端和API資源來配置ids4。
    services.AddIdentityServer()
        .AddDeveloperSigningCredential()
        .AddInMemoryApiResources(Config.GetApiResources())
        .AddInMemoryClients(Config.GetClients());
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env,ILoggerFactory loggerFactory)
{

    loggerFactory.AddConsole(LogLevel.Debug);
    app.UseDeveloperExceptionPage();

    app.UseIdentityServer();

}

執行此專案,開啟瀏覽器訪問http://localhost:5000/.well-known/openid-configuration你將會看到所謂的發現文件。

七.新增API

在專案Api中新增一個Controller

[Route("[controller]")]
[Authorize]
public class IdentityController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
    }
}

稍後將使用此控制器來測試授權,以及通過API來檢視身份資訊單元(Claim)。

配置

新增身份驗證中介軟體

  • 驗證傳入令牌以確保它來自可信發行者。
  • 令牌驗證是有效的,用於在這個API

在專案中新增nuget包Microsoft.AspNetCore.Authentication.JwtBearer

這裡使用了Microsoft.AspNetCore.Authentication.JwtBearer包來替換AccessTokenValidation,因為後者還沒有更新到.net core 2.0,使用的話,是有問題的

您還需要將中介軟體新增到管道中。它必須在MVC之前新增:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvcCore().AddJsonFormatters();
    services.AddAuthentication((options) =>
        {
            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters();
            options.RequireHttpsMetadata = false;
            options.Audience = "api1";//api範圍
            options.Authority = "http://localhost:5000";//IdentityServer地址
        });
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseAuthentication();
    app.UseMvc();
}

八.建立客戶端

最後一個步驟是編寫一個客戶端來請求訪問令牌,然後使用這個令牌來訪問 API。為此你需要為你的解決方案新增一個控制檯應用程式。

IdentityServer 上的令牌端點實現了 OAuth 2.0 協議,你應該使用合法的 HTTP請求來訪問它。然而,我們有一個叫做 IdentityModel 的客戶端庫,它將協議互動封裝到了一個易於使用的 API 裡面。

新增 IdentityModel NuGet 程式包到你的客戶端專案中。

IdentityModel 包含了一個用於 發現端點 的客戶端庫。這樣一來你只需要知道 IdentityServer 的基礎地址,實際的端點地址可以從元資料中讀取:

// 從元資料中發現埠
var disco = await DiscoveryClient.GetAsync("http://localhost:5000");

接著你可以使用 TokenClient 來請求令牌。為了建立一個該型別的例項,你需要傳入令牌端點地址、客戶端id和密碼。

然後你可以使用 RequestClientCredentialsAsync 方法來為你的目標 API 請求一個令牌:

// 請求令牌
var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret");
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1");

if (tokenResponse.IsError)
{
    Console.WriteLine(tokenResponse.Error);
    return;
}

Console.WriteLine(tokenResponse.Json);

注意:從控制檯中複製和貼上訪問令牌到 jwt.io 以檢查令牌的合法性。

最後是呼叫 API。

為了傳送訪問令牌到 API,你一般要使用 HTTP 授權 header。這可以通過 SetBearerToken 擴充套件方法來實現:

// 呼叫api
var client = new HttpClient();
client.SetBearerToken(tokenResponse.AccessToken);

var response = await client.GetAsync("http://localhost:5001/identity");
if (!response.IsSuccessStatusCode)
{
    Console.WriteLine(response.StatusCode);
}
else
{
    var content = await response.Content.ReadAsStringAsync();
    Console.WriteLine(JArray.Parse(content));
}

依次啟動QuickstartIdentityServer>API>Client
最後檢視輸出結果:

注意:預設情況下訪問令牌將包含 scope 身份資訊,生命週期(nbf 和 exp),客戶端 ID(client_id) 和 發行者名稱(iss)。

進一步實踐
當前演練目前主要關注的是成功的步驟:

  • 客戶端可以請求令牌
  • 客戶端可以使用令牌來訪問 API

你現在可以嘗試引發一些錯誤來學習系統的相關行為,比如:

  • 嘗試在 IdentityServer 未執行時(unavailable)連線它
  • 嘗試使用一個非法的客戶端id或密碼來請求令牌
  • 嘗試在請求令牌的過程中請求一個非法的 scope
  • 嘗試在 API 未執行時(unavailable)呼叫它
  • 不向 API 傳送令牌
  • 配置 API 為需要不同於令牌中的 scope

九.使用Postman除錯

十.專案所用程式碼

相關推薦

IdentityServer47- 使用客戶認證控制API訪問客戶授權模式

一.前言 目前官方的文件和Demo以及一些相關元件全部是.net core 1.1的,應該是因為目前IdentityServer4目前最新版本只是2.0.0 rc1的原因,官方文件和Demo還沒來更新。我準備使用的是.net core 2.0 所支援的IdentityServer4 2.0.0,官方文件及De

IdentityServer48- 使用密碼認證方式控制API訪問資源所有者密碼授權模式

原文: IdentityServer4(8)- 使用密碼認證方式控制API訪問(資源所有者密碼授權模式) 一.前言 本文及IdentityServer這個系列使用的都是基於.net core 2.0的。上一篇博文在API專案中我使用了Microsoft.AspNetCore.Authentication.

以太坊go-ethereum客戶JSON-RPC API呼叫

前幾篇部落格主要介紹了go-ethereum客戶端不同環境的搭建,今天這篇部落格是建立在前幾排部落格的基礎上。當搭建完成之後,我們可以通過各種方式與節點進行互動(JavaScript Console、JSON-RPC 、web3等)。本篇以建立一個賬戶為例,介紹

極光推送 java 服務推送api demo不使用官方的sdk

極光推送  java 服務端推送api  demo(不使用官方的sdk)1 極光推送的核心類如下:import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.asse

網頁無法使用安卓微信瀏覽器開啟安卓手機:該證書並非來自可信賴的授權中心

生成二維碼的時候發現網頁無法在微信瀏覽器裡開啟,檢查了二維碼對應的URL連結沒有錯誤,在CHROME裡也能開啟,用安卓自帶的手機瀏覽器開啟時,提示:該證書並非來自可信賴的授權中心。 使用這個SSL檢查站檢查,發現前四項正常,第五項報錯:A valid Root CA Certificate

FreeRTOS學習筆記1---任務建立與刪除API函式動態函式

FreeRTOS最基本的功能是任務管理,任務管理有建立與刪除任務 1.函式xTaskCreate()     此函式用來建立一個任務,使用此函式來建立任務所需的RAM(隨機儲存器)會從FreeRTOS的堆中分配,因此必須提供記憶體管理檔案,預設使用heap_4.c這個

API 限流器:基於redis的API訪問頻率控制器的實現

 在open API日益盛行的今天,API的訪問頻率控制尤為重要。Google開源的Guava中有個類叫RateLimiter,但是此類控制粒度只是秒級別的,沒有提供分鐘,小時,天級別的限制,而且採取的是阻塞的模式,應用起來不是很方便。本人依據Redis的有序集合開發了一個訪

QBuffer簡單操作被看做一個標準的可隨機訪問的檔案,支援訊號

Qt中通過QBuffer類我們可以使用io的方式訪問、操作QByteArray中的內容。此時,QByteArray被看做一個標準的可隨機訪問的檔案。例如: QBuffer buffer; char ch; buffer.open(QBuffer::ReadWrite); buffer.write("Qt

springCloud7:Ribbon實現客戶側負載均衡-消費者整合Ribbon

spring cloud ribbon 消費者整合ribbon 一、簡介 Ribbon是Netfix發布的負載均衡器,它有助於控制HTTP和TCP客戶端的行為。為Ribbon配置服務提供者地址列表後,Ribbon就可基於某種負載均衡算法,自動地幫助服務消費者去請求。Ribbon默認為我們提供了很

大資料入門7RPC客戶和RPC服務通訊

RPC客戶端和RPC服務端通訊: 客戶端:(匯入jar:hdfs,common相關的) LoginControl: public class LoginControl {     public static void main(String[] args) th

Redis7-----初識Redis-----客戶對Redis叢集的使用方法

記得連結之前關閉防火牆,或者把本埠號新增到防火牆例外 [[email protected]0723 bin]# service iptables stop -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p

大資料教程7.4HDFS的java客戶API流處理方式

        博主上一篇部落格分享了namenode和datanode的工作原理,本章節將繼前面的HDFS的java客戶端簡單API後深度講述HDFS流處理API。       &nb

IdentityServer4-客戶授權模式原理分析

原文: IdentityServer4-客戶端的授權模式原理分析(三) 在學習其他應用場景前,需要了解幾個客戶端的授權模式。首先了解下本節使用的幾個名詞 Resource Owner:資源擁有者,文中稱“user”; Client為第三方客戶端; Authorization server為授權伺服器;

ONVIF協議網路攝像機IPC客戶程式開發7:裝置搜尋

1 專欄導讀 本專欄第一篇文章「專欄開篇」列出了專欄的完整目錄,按目錄順序閱讀,有助於你的理解,專欄前面文章講過的知識點(或程式碼段),後面文章不會贅述。為了節省篇幅,突出重點,在文章中展示的示例程式碼僅僅是關鍵程式碼,你可以在「專欄開篇」中獲取完整程式碼。

如何用Tomcat和Openssl構建HTTPS雙向認證環境HTTPS客戶認證

本文將介紹如何利用Tomcat的HTTPS功能,和一個自己建立的CA,來構建WEB伺服器證書和個人數字證書,最終建成一個HTTPS雙向認證環境(可以用於測試目的)。本文構建HTTPS雙向認證的業務流程大致如下:  1. 建立WEB伺服器公鑰金鑰,並生成伺服器證書請求。  2.

淘淘商城系列——使用FastDFS-Client客戶進行上傳圖片的測試

row 構造方法 無法 空間 依賴 ron 文件下載 信息 utils http://blog.csdn.net/yerenyuan_pku/article/details/72804018 不久之前,我們實現了商品的類目選擇這個功能,但這只是萬裏長征的第一步,我們還有很

7javascript的程序控制結構及語句------2循環控制語句、跳轉語句、對話框

對話 ima bsp .cn while語句 prompt 彈出 asc div 一、循環控制語句 循環語句主要就是在滿足條件的情況下反復執行某一個操作,循環控制語句主要包括while語句、do...while語句 和for語句。 1、While

初涉掃碼登錄:edusoho實現客戶掃碼登錄簡版

confirm 鍵值 版本號 error == form 通過 遮罩層 strrev 一、項目簡介及需求 edusoho是一套商業版的在線教育平臺,項目本身基於symfony2框架開發,現在有一款自己的APP,要求在不多修改edusoho自身代碼的基礎上,實現客戶端對P

一個基於JRTPLIB的輕量級RTSP客戶(myRTSPClient)——實現篇:RTP音視頻傳輸解析層之音視頻數據傳輸格式

客戶端 會有 服務 client 基本 cnblogs 存在 額外 導致 一、差異 本地音視頻數據格式和用來傳輸的音視頻數據格式存在些許差異,由於音視頻數據流到達客戶端時,需要考慮數據流的數據邊界、分包、組包順序等問題,所以傳輸中的音視頻數據往往會多一些字節。 舉個例子