一区在线电影,国产在线首页,中文字幕精,天天爽天天射,夜色99,日韩国产成人av,伊人久久综合视频

威勢(shì)網(wǎng)絡(luò),為您的企業(yè)和團(tuán)隊(duì)注入互聯(lián)網(wǎng)活力!
服務(wù)熱線:138-9741-0341

[原創(chuàng)] IdentityServer4權(quán)限控制---客戶端創(chuàng)建、獲取TOKEN及訪問(wèn)API資源(三)

發(fā)布日期:2022/9/3 作者: 瀏覽:1146

    經(jīng)過(guò)前面兩節(jié)課,我們已經(jīng)完成了API服務(wù)器的搭建與IDS4身份驗(yàn)證服務(wù)器的搭建,如果還沒(méi)有看的朋友請(qǐng)到這里圍觀:


[原創(chuàng)] IdentityServer4權(quán)限控制---客戶端授權(quán)模式之API服務(wù)器搭建(一)

[原創(chuàng)] IdentityServer4權(quán)限控制---客戶端授權(quán)模式之IDS4認(rèn)證服務(wù)器搭建(二)


    API服務(wù)器是我們要保護(hù)的資源服務(wù)器,我們希望只授權(quán)給通過(guò)身份驗(yàn)證的客戶端去訪問(wèn),而身份驗(yàn)證的工作是由我們搭建的IDS4服務(wù)器來(lái)完成的?,F(xiàn)在我們模擬一個(gè)場(chǎng)景,我們已經(jīng)將上面兩臺(tái)服務(wù)器成功部署到公司的服務(wù)器上去了,現(xiàn)在有個(gè)第三方用戶,他開(kāi)發(fā)了一頭桌面應(yīng)用,叫做client.exe,該應(yīng)用在成功運(yùn)行以后要讀取我們的資源服務(wù)器上的接口數(shù)據(jù),也就是訪問(wèn) https://localhost:6001/上面的三個(gè)接口數(shù)據(jù),我們希望只對(duì)身份已經(jīng)證的用戶開(kāi)放,并不是隨便人寫(xiě)幾行代碼就把我們的數(shù)據(jù)給偷走了,這里CLIENT.EXE就是我們的客戶端,為此我簡(jiǎn)單畫(huà)了一張圖,如下:

(注意:步驟4、5、5'是假想的,我們要通過(guò)實(shí)驗(yàn)去驗(yàn)證它是否存在)

    客戶端程序?yàn)榱嗽L問(wèn)API資源服務(wù)器上的接口數(shù)據(jù),先要進(jìn)行身份驗(yàn)證才可以,不然會(huì)被資源服務(wù)器拒絕,所以,它要先去IDS4服務(wù)器申請(qǐng)TOKEN,申請(qǐng)TOKEN需要攜帶必要的身份信息,上圖左下角橘色框中便是。成功拿到TOKEN以后,客戶端再發(fā)起一個(gè)網(wǎng)絡(luò)連接,去申請(qǐng)API資源,這個(gè)過(guò)程中要向API資源服務(wù)器提交身份認(rèn)證用的TOKEN,右下角綠色便是。為了流程理解方便,我在上面標(biāo)注了數(shù)據(jù)代表步驟順序。資源服務(wù)器得到TOKEN以后,是JWT格式的,直接在本機(jī)驗(yàn)證,(這里要特別注意一下?。?!,也就是說(shuō):步驟3以后直接返回,而不是通過(guò)步驟45后再返回。

    現(xiàn)在我們需要去打造一個(gè)客戶端client.exe去申請(qǐng)我們的TOKEN以及訪問(wèn)我們的資源。

創(chuàng)建一個(gè)控制臺(tái)程序

選擇新建目錄

選擇.NET6.0下一步,就建好了。我們的直接用官網(wǎng)提供的代碼去測(cè)試,如下,


// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using IdentityModel.Client;
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace Client
{
    public class Program
    {
        private static async Task Main()
        {
            // discover endpoints from metadata
            var client = new HttpClient();

            var disco = await client.GetDiscoveryDocumentAsync("https://localhost:5001"); //取得證書(shū) https://localhost:5001/.well-known/openid-configuration
            if (disco.IsError)
            {
                Console.WriteLine(disco.Error);
                return;
            }

            // 請(qǐng)求token令牌
            var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
            {
                Address = disco.TokenEndpoint,
                ClientId = "client",
                ClientSecret = "secret",
                Scope = "api1"
                //Scope = "identity"
            });

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

            Console.WriteLine(tokenResponse.Json);//輸出令牌信息
            Console.WriteLine("\n\n");

            // call api 訪問(wèn)我們的API資源,注意,每個(gè)資源的權(quán)限要求是不一樣的
            var apiClient = new HttpClient();
            apiClient.SetBearerToken(tokenResponse.AccessToken);

            var response = await apiClient.GetAsync("https://localhost:6001/identity"); //該資源要求登錄用戶才可以訪問(wèn)
            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.StatusCode);
            }
            else
            {
                var content = await response.Content.ReadAsStringAsync();
                Console.WriteLine(JArray.Parse(content));
            }

            response = await apiClient.GetAsync("https://localhost:6001/api/Students");  //該資源匿名可訪問(wèn)
            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.StatusCode);
            }
            else
            {
                var content = await response.Content.ReadAsStringAsync();
                Console.WriteLine(JArray.Parse(content));
            }
        }
    }
}
我們把IdentityModel包引起去,再把Newtonsoft.Json也引進(jìn)去,在第二課中講到,Identity  接口是要驗(yàn)證用戶才可以訪問(wèn)成功的,未登錄用戶返回401?,F(xiàn)在我們運(yùn)行client.exe試試,運(yùn)行之前先運(yùn)行我們的API服務(wù)器與身份驗(yàn)證服務(wù)器,再運(yùn)行client.exe,看到CMD窗口返回以下信息:


{"access_token":"eyJhbGciOiJSUzI1NiIsImtpZCI6IkU1OEMxMkExMUU3NTkwRTk3NEY3REREQTA3NEIwRTUwIiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE2NjIxOTcyMzMsImV4cCI6MTY2MjIwMDgzMywiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NTAwMSIsImNsaWVudF9pZCI6ImNsaWVudCIsImp0aSI6IjU3RDA4MkIxN0NFRjUxM0M4MzVFRENFNzkxQ0NGRDJGIiwiaWF0IjoxNjYyMTk3MjMzLCJzY29wZSI6WyJhcGkxIl19.pYY8nTQvHQMeKjn5LkE-OO2xzsnS4xyicusJ88SMyThqelFq95fhqZC3jUoOFqDUy8ex7S1Q_c8RL0G3dnvuIIiyg6ECPxRBNHwVfztdzVpoe7qOEyYdP_Z9lqwcgJdbWiWCGzcPkWzErikFIHDe2KwprD1_YlDBN67ze96sVWypNrSBWhFgPf80B3wfDSE3z1apoz0Pe8QqkoWpE9xT-Y0_vz5s3m-CaNl6ar8M1Wk2LdvDYwk3UgJ5p4XViwtookPUj48rKVseohe7qQtTpXpT0RXf0JLuXmAhxRMweXBZMNY64F-d9MbqftyBKlDffXTgoK8JeaujcYdZ9nLy6A","expires_in":3600,"token_type":"Bearer","scope":"api1"}



[
  {
    "type": "nbf",
    "value": "1662197233"
  },
  {
    "type": "exp",
    "value": "1662200833"
  },
  {
    "type": "iss",
    "value": "https://localhost:5001"
  },
  {
    "type": "client_id",
    "value": "client"
  },
  {
    "type": "jti",
    "value": "57D082B17CEF513C835EDCE791CCFD2F"
  },
  {
    "type": "iat",
    "value": "1662197233"
  },
  {
    "type": "scope",
    "value": "api1"
  }
]
[
  {
    "boinYear": 1986,
    "xingMing": "QiQi",
    "age": 36,
    "address": "中國(guó)"
  },
  {
    "boinYear": 1970,
    "xingMing": "Black Smith",
    "age": 52,
    "address": "英國(guó)"
  },
  {
    "boinYear": 1957,
    "xingMing": "John",
    "age": 65,
    "address": "日本"
  },
  {
    "boinYear": 1975,
    "xingMing": "John",
    "age": 47,
    "address": "加拿大"
  },
  {
    "boinYear": 1975,
    "xingMing": "QiQi",
    "age": 47,
    "address": "美國(guó)"
  }
]


LOOK,我們成功獲取到了Identity接口的數(shù)據(jù)!我們接著文章開(kāi)始處留下的問(wèn)題分別做這樣的實(shí)驗(yàn):

一、在 client.exe從identityserver4獲得tokenResponse.AccessToken后,將identityserver4服務(wù)器關(guān)閉,分別訪問(wèn)兩個(gè)API接口。

二、在獲得tokenResponse.AccessToken后,將它保存下來(lái),然后關(guān)閉identityserver4服務(wù)器,也就是說(shuō),用上次獲得到TOKEN,在驗(yàn)證服務(wù)器關(guān)閉的狀態(tài)下去訪問(wèn)API資源。

通過(guò)上面的實(shí)驗(yàn),我們知道,在identityserver4關(guān)閉的時(shí)候,我們的身份驗(yàn)證照常可以通過(guò),也就是說(shuō),登錄獲得TOKEN是在Identityserver4上進(jìn)行的,而獲得TOKEN以后就沒(méi)它什么事了。文章開(kāi)始處的流程圖中4、5、5‘ 步驟是不存在的。

這樣,我們的客戶端就只有通過(guò)了身份驗(yàn)證才可以訪問(wèn)到我們的資源,也就是說(shuō)資源得到了保護(hù)。但是很多小伙伴要問(wèn)了,你這也太粗暴了吧!我怎么樣對(duì)API的資源進(jìn)行更精細(xì)化的保護(hù)呢? 別著急,我們打開(kāi)APITEST項(xiàng)目,在program.cs 中寫(xiě)一個(gè)權(quán)限策略來(lái)實(shí)現(xiàn)更精細(xì)化的控制。


builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("ApiScope", policy =>
    {
        policy.RequireAuthenticatedUser();
        policy.RequireClaim("scope", "api1");
    });
});
就這樣,我們?cè)趐rogram.cs啟動(dòng)之時(shí)注冊(cè)了一個(gè)安全策略,我們只需要在需要驗(yàn)證的地放這樣去引用就可以了



    //[Authorize]
    [Authorize(Policy = "ApiScope")]
這樣就不是所有登錄的用戶都可以訪問(wèn)我們的資源了,而是需要滿足ApiScope策略的用戶才可以!根據(jù)這個(gè)原理,我們可以擴(kuò)展很多。IDS4官方宣稱,給資源一個(gè)別名是比較推薦的一種做法,給了別名,其實(shí)就可以用不同的別名來(lái)授權(quán)。嘗試將API服務(wù)器換成域名,和IDS4分別不同的域名,讓客戶端跨域申請(qǐng)TOKEN及授權(quán),任然是可以的,看來(lái)還是比較方便的,其它功能等后面研究再深入一些,我再回來(lái)補(bǔ)充。。。

今天的源碼下載

看文章一天,寫(xiě)文章一天,寫(xiě)作不易,朋友們留言支持一下就不勝感激了。。。

原創(chuàng)文章,創(chuàng)作不易,轉(zhuǎn)載請(qǐng)注明出處:http://www.maiyt.com/article-29


下拉加載更多評(píng)論
最新評(píng)論
暫無(wú)!