IdentityServer4 QuckStart 授權與自定義Claims

来源:https://www.cnblogs.com/podolski/archive/2020/04/19/12734603.html
-Advertisement-
Play Games

最近在折騰IdentityServer4,為了簡單,直接使用了官方給的QuickStart示例項目作為基礎進行搭建。有一說一,為了保護一個API,感覺花費的時間比寫一個API還要多。 本文基於ASP.NET CORE 3.1, IdentityServer4 3.1.3。代碼皆為關鍵代碼,貼全了太多 ...


最近在折騰IdentityServer4,為了簡單,直接使用了官方給的QuickStart示例項目作為基礎進行搭建。有一說一,為了保護一個API,感覺花費的時間比寫一個API還要多。

本文基於ASP.NET CORE 3.1, IdentityServer4 3.1.3。代碼皆為關鍵代碼,貼全了太多了。

好不容易跑起來了,最終的任務要落實到授權的工作上來。在API中使用Authorize用來限制用戶的訪問。

[Route("api/[controller]")]
[Authorize(Roles = "Administrator")]
[ApiController]
public class UserInfoController : ControllerBase
{
    /// <summary>
    /// 無參GET請求
    /// </summary>
    /// <returns></returns>
    [HttpGet()]
    [ProducesResponseType(typeof(ReturnData<IEnumerable<UserInfo>>), Status200OK)]
    public async Task<ActionResult> Get()
    {
        var info = new Info<UserInfo>();
        return Ok(new ReturnData<IEnumerable<UserInfo>>(await info.Get()));
    }

然而在使用的時候,雖然正確取得授權,但是卻無法正常訪問API,一直提示401沒有授權錯誤。仔細檢查,發現IdentityServer4返回的內容並沒有返回role的JwtClaimTypes,沒有它,Authorize無法正常工作。

{
    "nbf": 1587301921,
    "exp": 1587305521,
    "iss": "http://localhost:5000",
    "aud": "MonitoringSystemApi",
    "client_id": "webClient",
    "sub": "c6c18d4d-c28e-4de5-86dd-779121216204",
    "auth_time": 1587301921,
    "idp": "local",
    "scope": [
        "roles",
        "MonitoringSystemApi",
        "offline_access"
    ],
    "amr": [
        "pwd"
    ]
}

實現

查看Config.cs,IdentityServer4預設只返回兩種IdentityResource:openid和profile。按照官方的說法,這個東西定義的內容會返回到用戶的token。參考。那麼就果斷給它安排。

public static IEnumerable<IdentityResource> Ids =>
new List<IdentityResource>
{
    new IdentityResources.OpenId(),
    new IdentityResources.Profile(),
    new IdentityResource ("roles", new List<string> { JwtClaimTypes.Role }){ Required = true}
};

public static IEnumerable<Client> Clients =>
    new List<Client>
    {
        new Client
        {
            ClientId = "webClient",
            ClientSecrets = { new Secret("secret".Sha256()) },
            AllowOfflineAccess = true,
            AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
            // scopes that client has access to
            AllowedScopes = {
                "roles",

                "MonitoringSystemApi" }
        },

執行之前,需要確保資料庫中的用戶數據,已經包含role的Claim。

//添加用戶代碼
bob = new ApplicationUser
{
    UserName = "bob"
};
var result = userMgr.CreateAsync(bob, "Pass123$").Result;
if (!result.Succeeded)
{
    throw new Exception(result.Errors.First().Description);
}
result = userMgr.AddClaimsAsync(bob, new Claim[]{
new Claim(JwtClaimTypes.Role, "Administrator"),
new Claim(JwtClaimTypes.Name, "Bob Smith"),

運行程式,返回值依舊沒有任何變化,很挫敗,只能繼續折騰。
研究通過實現IProfileService達到自定義Cliams。文章寫的很詳細,我這就不重覆了,我實際試驗過,可以成功。

但是文章末尾的註意,很重要。

“那麼, 通過profileservice頒發的claims, 任意clients都能拿到”

說明這個優先順序是非常高的,可以覆蓋所有的行為,當然我們可以在IProfileService的實現上對許可權進行進一步的設置,不過還是挺麻煩的。參考實現參考官方

作為懶人,必然不想再費勁去折騰許可權的問題,那麼是否有簡單點的辦法呢?

網上有一些問答說到了可以通過設置Scopes來達到目的。不過過於久遠,IdentityServer4已經沒有這個獨立的類了,說是已經被ApiResource取代了。

直覺上這個東西應該是指示要保護的API的相關內容的,好像和這個沒啥關係,不過也只能死馬當活馬醫了。修改config.cs,最終如下內容:

public static IEnumerable<ApiResource> Apis =>
new List<ApiResource>
{
    new ApiResource("pls", new[]{ "role"}),
};

public static IEnumerable<Client> Clients =>
new List<Client>
{
new Client
{
    ClientId = "webClient",
    ClientSecrets = { new Secret("secret".Sha256()) },
    AllowOfflineAccess = true,
    AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
    // scopes that client has access to
    AllowedScopes = {
        "pls"
        }
},

返回結果如下:

{
    "nbf": 1587301799,
    "exp": 1587305399,
    "iss": "http://localhost:5000",
    "aud": "pls",
    "client_id": "webClient",
    "sub": "c6c18d4d-c28e-4de5-86dd-779121216204",
    "auth_time": 1587301799,
    "idp": "local",
    "role": "Administrator",
    "scope": [
        "pls",
        "offline_access"
    ],
    "amr": [
        "pwd"
    ]
}

終於看見心心念念的自定義Claim(role),可以去訪問API了。

註意,在Client中也有個Claims,添加了role並且設置AlwaysSendClientClaimsAlwaysIncludeUserClaimsInIdToken之後,會在token中添加client_roie欄位,這個是沒辦法用與授權的,可以理解為IdentityServer4直接指定了Client角色,並不是Identity中的角色概念。

後記

回過頭來仔細看官方的文檔,ApiResource中的UserClaims就是用來乾這個的,折騰了半天,不如當時仔細看看文檔了。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言: Python可謂是現在很多人正在學或者想學的一個腳本語言了,提到學習自然就少不了拿項目練手,可是一般的項目根本提不起興趣嘛,這10個項目可是非常有趣的,不信你看看。 【Python 圖片轉字元畫】 用 50 行 Python 代碼完成圖片轉字元畫小工具。通過實驗將學習到 Linux 命令行操 ...
  • 給定四種水果,分別是蘋果(apple)、梨(pear)、桔子(orange)、葡萄(grape),單價分別對應為3.00元/公斤、2.50元/公斤、4.10元/公斤、10.20元/公斤。首先在屏幕上顯示以下菜單:[1] apple[2] pear[3] orange[4] grape[0] exit... ...
  • 一、全局修改 打開即可修改 二、針對當前項目修改 ...
  • 一、I/O操作概述 I/O概述: I/O在電腦中時指Input/Output,也就是Stream的輸入與輸出。我們通常說的輸入與輸出其實在操作系統中都是相對於記憶體而言的,InputStream(輸入流)是指數據從外部(網路、鍵盤、I/O設備)流進記憶體,OutputStream正好與之相反,數據從內 ...
  • 本題要求編寫程式,輸出菲波那契(Fibonacci)數列的前N項,每行輸出5個,題目保證輸出結果在長整型範圍內。Fibonacci數列就是滿足任一項數字是前兩項的和(最開始兩項均定義為1)的數列,例如:1,1,2,3,5,8,13,...。輸入格式:輸入在一行中給出一個整數N(1≤N≤46)。輸出格... ...
  • 一、Sublist導致OOM 代碼 @Slf4j public class SubListDemo { public static void subListOOM() { List<List<Integer>> data = new ArrayList<>(); for (int i = 0; i ...
  • 博主是一個在校大學生。在家學習javaweb項目的時候需要用到很多jar包,在網上搜jar包被各種坑,當然也有一些博主會分享到雲盤以供我們下載。 偶然間知道了一個專門為jar包下載的網站,而且是免費下載,就想著分享出來,不讓初學javaweb的小白為jar包下載而發愁。 當然啦,這也是博主的第一篇博 ...
  • 在Asp.net Core之前所有的Action返回值都是ActionResult,Json(),File()等方法返回的都是ActionResult的子類。並且Core把MVC跟WebApi合併之後Action的返回值體系也有了很大的變化。 ActionResult類 ActionResult類是 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...