1. 程式人生 > >IdentityServer4在Asp.Net Core中的應用(一)

IdentityServer4在Asp.Net Core中的應用(一)

types eid 應用 temp ant 所有 com 好用 nts

IdentityServer4是一套身份授權以及訪問控制的解決方案,專註於幫助使用.Net 技術的公司為現代應用程序建立標識和訪問控制解決方案,包括單點登錄、身份管理、授權和API安全。

下面我將具體介紹如何在.Net Core中實現OAuth授權,從最簡單的授權模式開始,在上一篇對OAuth2.0的詳細描述中,在客戶端模式中,我們說它在嚴格意義上講是不存在授權的問題,我們再來看下它的授權流程:

技術分享圖片

客戶端在向授權服務器申請令牌後,授權服務器直接將令牌返回給了客戶端,這個過程不需要其他角色的任何操作,只是客戶端和授權服務器的交互。我們結合具體的示例來進一步了解這個過程。

操作系統:Mac OS

開發工具:VS Code

調試工具:Postman

開發框架:.Net Core 2.0

在具體示例實現之前,先說一下在VS Code我們會用到的插件,以方便我們的開發,畢竟VS Code沒有我們宇宙第一IDE-Visual Studio那麽強大,但是也是目前為止最好用的編輯器,它提供了各式各樣的插件,幾乎滿足我們所有的開發需求。在這裏我們用到的一個插件叫做Nuget Package Manager,這個插件可以方便我們使用快捷鍵對Nuget包進行管理。

接下來我們首先創建一個授權服務器的項目,打開VS Code使用控制臺,創建一個WebApi的項目,使用命令:

 dotnet new WebApi -n IdentityServer4.Server

創建完成後,我們可以啟動查看我們的項目,run一下:

技術分享圖片

這樣我們的項目是可以運行成功的,下面我們進行添加IdentitServer4包的引用,在我們安裝了Nuget Package Manager後,我們可以快速的使用快捷鍵,在Mac系統中使用command+p,然後輸入">",然後輸入Nuget... (註意一定要切換到當前的項目下)會出現以下提示:

技術分享圖片

選擇第一個選項添加Package:

技術分享圖片

按回車,選擇IdentityServer4最新版本的安裝,這裏是2.1.3,安裝完後,我們在StartUp中添加IdentityServer4的引用,並使用AddIdentityServer()方法在依賴註入系統中註冊IdentityServer,當然這裏我們也可以等到添加完配置類後再進行操作。我們先添加一個配置類,叫做Config.cs,首先定義一個管道(Scope),指定我們所保護Api資源,該方法返回一個ApiResources集合,具體代碼如下:new ApiResource("api","UsersApi"),第一個參數為Api的名稱,第二個參數為顯示的名稱:

技術分享圖片

下一步進行客戶端註冊,定義給客戶端可以返回的資源,即允許哪個Scope定義,代碼如下:

技術分享圖片

下面我們將該配置註入到系統中,

技術分享圖片

AddDeveloperSigningCredential(),是一種RSA證書加密方式,它會生成一個tempkey.rsa證書文件,項目每次啟動時,會檢查項目根目錄是否存在該證書文件,若不存在,則會生成該文件,否則會繼續使用該證書文件。後面依次將ApiResources和Clients添加到內存中。

下一步是配置IdentityServer4的管道,在Configure裏面添加,app.UseIdentityServer(),在這裏我們用不到mvc,將app.UseMvc()註釋掉即可。下面我們運行我們的項目,當然直接訪問http://localhost:5000是看不到任何東西的,在這裏我們使用一個固定的地址http://localhost:5000/.well-known/openid-configuration,可以查看IdentityServer4的配置信息,運行格式化後內容如下:

{
    "issuer": "http://localhost:5000",
    "jwks_uri": "http://localhost:5000/.well-known/openid-configuration/jwks",
    "authorization_endpoint": "http://localhost:5000/connect/authorize",
    "token_endpoint": "http://localhost:5000/connect/token",
    "userinfo_endpoint": "http://localhost:5000/connect/userinfo",
    "end_session_endpoint": "http://localhost:5000/connect/endsession",
    "check_session_iframe": "http://localhost:5000/connect/checksession",
    "revocation_endpoint": "http://localhost:5000/connect/revocation",
    "introspection_endpoint": "http://localhost:5000/connect/introspect",
    "frontchannel_logout_supported": true,
    "frontchannel_logout_session_supported": true,
    "backchannel_logout_supported": true,
    "backchannel_logout_session_supported": true,
    "scopes_supported": [
        "api",
        "offline_access"
    ],
    "claims_supported": [],
    "grant_types_supported": [
        "authorization_code",
        "client_credentials",
        "refresh_token",
        "implicit"
    ],
    "response_types_supported": [
        "code",
        "token",
        "id_token",
        "id_token token",
        "code id_token",
        "code token",
        "code id_token token"
    ],
    "response_modes_supported": [
        "form_post",
        "query",
        "fragment"
    ],
    "token_endpoint_auth_methods_supported": [
        "client_secret_basic",
        "client_secret_post"
    ],
    "subject_types_supported": [
        "public"
    ],
    "id_token_signing_alg_values_supported": [
        "RS256"
    ],
    "code_challenge_methods_supported": [
        "plain",
        "S256"
    ]
}
這表明我們的IdentityServer已經配置成功,下面我們借助Postman模擬發起獲取令牌請求,我們使用token_point的地址:http://localhost:5000/connect/token獲取acces token,Postman配置如下: 技術分享圖片

上面指定的3個參數都是客戶端模式需要指定的參數,下面就是我們請求到的access token。接著我們創建一個Api,去調用我們的授權服務器進行授權,重復上面的步驟,創建一個WebApi項目,不再贅述,直接去配置調用授權服務器,這個項目只是一個Api的項目,不需要完整的IdentityServer4的引用,只引用一個IdentityServer4.AccessTokenValidation包就可以了。在授權服務器中我們已經占用5000端口,所以在這個項目中我們指定為5001端口,在Program.cs裏面指定5001端口,添加.UseUrls("http://localhost:5001"):

技術分享圖片

在ValuesController裏面添加 Microsoft.AspNetCore.Authorization的引用,並添加[Authorize]標簽,即要求該Controller要通過授權才可以訪問,

技術分享圖片

下面我們在StartUp.cs裏面去配置授權服務:

技術分享圖片

接著我們分別啟動授權服務器和Api,我們運行Api,訪問:http://localhost:5001/api/values ,訪問結果如下:技術分享圖片

提示Http Error 401 ,在狀態碼中401即未授權,我們把它拿到Postman中運行:

技術分享圖片

我們在Headers中指定Authorization 模式為Bearer,狀態401 未授權,這個結果也是我們意料中的結果了,因為我們並未獲取到令牌,我們繼續使用Postman模擬獲取到access token,

技術分享圖片

我們將獲取到的access_token放到Api的Headers裏面:

技術分享圖片

註意令牌與Bearer中間加空格,接下來繼續請求:

技術分享圖片

這樣我們就拿到了Api裏面要獲取的值了,到這裏我們使用Postman驗證了我們的結果,下面我們再創建一個第三方應用,去請求我們的Api資源,繼續了解我們的授權流程,客戶端我使用控制臺程序進行測試。

我們繼續使用命令行創建第三方應用,名稱為ThirdPartyApplication,IdentityServer4有一個專門專門為客戶端程序用的Nuget包,叫做IdentityModel,我們還是通過快捷鍵添加Nuget Package,下面直接上代碼,必要說明會在代碼中直接註釋:

using System;
using System.Net.Http;
using IdentityModel;
using IdentityModel.Client;


namespace ThirdPartyApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            //請求授權服務器
            var diso=DiscoveryClient.GetAsync("http://localhost:5000").Result;
            if(diso.IsError)
            {
                Console.WriteLine(diso.Error);
            }

            //授權服務器根據客戶端發來的請求返回令牌
            var tokenClient=new TokenClient(diso.TokenEndpoint,"Client","secret");
            var tokenResponse=tokenClient.RequestClientCredentialsAsync("api").Result;
            if(tokenResponse.IsError)
            {
                Console.WriteLine(tokenResponse.Error);
            }
            //如果成功,則打印輸出返回的令牌信息
            else
            {
                Console.WriteLine(tokenResponse.Json);
            }

            //創建HttpClient對象
            var httpClient=new HttpClient();

            //設置Authorization的Value值
            httpClient.SetBearerToken(tokenResponse.AccessToken);

            //根據授權服務器返回的令牌信息請求Api資源
            var response= httpClient.GetAsync("http://localhost:5001/api/values").Result;

            //如果返回結果為成功,輸出Api資源的結果
            if(response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
        }
    }
}

下面輸出結果:

技術分享圖片

以上就是我們整個OAuth2.0授權模式中完整的客戶端授權模式了,以上流程簡化如下:

技術分享圖片

後面文章會繼續講解其他幾種授權模式的使用。各位,晚安。

技術分享圖片

掃描二維碼關註我的公眾號,共同學習,共同進步!

IdentityServer4在Asp.Net Core中的應用(一)