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

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

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

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

    操做系統:Mac OSsession

    開發工具:VS Codemvc

    調試工具:Postmanapp

    開發框架:.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一下:post

這樣咱們的項目是能夠運行成功的,下面咱們進行添加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受權模式中完整的客戶端受權模式了,以上流程簡化以下:

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

掃描二維碼關注個人公衆號,共同窗習,共同進步!

相關文章
相關標籤/搜索