1. 程式人生 > >IdentityServer4實現.Net Core API介面許可權認證(快速入門)

IdentityServer4實現.Net Core API介面許可權認證(快速入門)

什麼是IdentityServer4

官方解釋:IdentityServer4是基於ASP.NET Core實現的認證和授權框架,是對OpenID Connect和OAuth 2.0協議的實現。

通俗來講,就是服務端對需要認證授權的資源(客戶端請求資源)在外層使用IdentityServer4框架進行封裝加殼,使用者只能通過獲取IdentityServer4頒發的Token令牌才能進行資源訪問。

下面開始進入正題,如何快速搭建實現API介面鑑權。

準備:1.下載準備NetCore sdk環境

           2.本文開發環境為VS2019,部分程式碼可能和之前的版本不同。

第一步,新建許可權認證服務專案,本文以Net Core API專案模板為例(也可以選擇其他模板)

第二步,新增IdentityServer4 Nuget程式包。不同版本依賴的NetCoe sdk環境不同,需手動選擇合適版本。

 

 

 

這裡提醒一下,有些同學的系統可能新增Nuget程式包時,發現無法找到程式包。我們這裡找出瞭解決方法,點選Nuget程式包新增頁面的右上角設定按鈕,看到如下頁面,手動新增如下的nuget.org,然後重新搜尋即可。

 

 

 

 

 

 第三步,新增IdentityServer4配置管理類。本文以使用者密碼授權模式為例。

 1 public class Config
 2     {
 3         /// <summary>
 4         /// 定義資源範圍
 5         /// </summary>
 6         public static IEnumerable<ApiResource> GetApiResources()
 7         {
 8             return new  List<ApiResource>
 9             {
10                 new ApiResource("api1", "我的第一個API")
11             };
12         }
13 
14         /// <summary>
15         /// 定義訪問的資源客戶端
16         /// </summary>
17         /// <returns></returns>
18         public static IEnumerable<Client> GetClients()
19         {
20             return new List<Client>
21             {
22                new Client{
23                    ClientId="client",//定義客戶端ID
24                    ClientSecrets=
25                    {
26                        new Secret("secret".Sha256())//定義客戶端祕鑰
27                    },
28                    AllowedGrantTypes=GrantTypes.ResourceOwnerPassword,//授權方式為使用者密碼模式授權,型別可參考GrantTypes列舉
29                    AllowedScopes={ "api1"}//允許客戶端訪問的範圍
30 
31                }
32              };
33         }
34 
35         /// <summary>
36         /// 這個方法是來規範tooken生成的規則和方法的。一般不進行設定,直接採用預設的即可。
37         /// </summary>
38         /// <returns></returns>
39         public static IEnumerable<IdentityResource> GetIdentityResources()
40         {
41             return new IdentityResource[]
42             {
43                 new IdentityResources.OpenId()
44             };
45         }
46     }

第四步,Startup啟動類中註冊服務中介軟體

 1 // This method gets called by the runtime. Use this method to add services to the container.
 2         public void ConfigureServices(IServiceCollection services)
 3         {
 4             services.AddIdentityServer()//註冊服務
 5                 .AddDeveloperSigningCredential()
 6                 .AddInMemoryApiResources(Config.GetApiResources())//配置類定義的授權範圍
 7                 .AddInMemoryClients(Config.GetClients())//配置類定義的授權客戶端
 8                 .AddTestUsers(new List<TestUser> { new TestUser { Username = "Admin", Password = "123456", SubjectId = "001", IsActive = true } });//模擬測試使用者,這裡偷懶了,使用者可以單獨管理,最好不要直接在這裡New
 9             services.AddControllers();
10         }
11 
12         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
13         public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
14         {
15             if (env.IsDevelopment())
16             {
17                 app.UseDeveloperExceptionPage();
18             }
19 
20             app.UseIdentityServer();//新增中介軟體
21             
22             app.UseHttpsRedirection();
23 
24             app.UseRouting();
25 
26             app.UseAuthorization();
27 
28             app.UseEndpoints(endpoints =>
29             {
30                 endpoints.MapControllers();
31             });
32         }

 

應用程式預設的埠號有兩種:1.http://localhost:5000   2.https://localhost:5001.

 

到這裡,Identityserver4鑑權服務已經簡單搭建完成。我們直接在VS中啟動專案。並在埠號後面加上/.well-known/openid-configuration,出現如下頁面則表示配置成功。

 

 

 

第五步,PostMan模擬請求獲取token(當然這一步非必須,對postman感興趣的同學可以試一試)

我們都知道IdentityServer4需要客戶端先訪問鑑權服務獲取token令牌,才能進一步訪問加權的伺服器資源。我們這裡先通過PostMan模擬客戶端請求,獲取Token。(postman工具大家可以網上下載,也可以使用谷歌自帶的postman外掛)

1.使用postman請求token時,有個地方需要注意下:

很多同學在使用https請求時,即請求https://localhost:5001,會發現無法成功。因為postman預設把SSL證書認證打開了,我們可以手動關閉掉。找到postman頁面右上方的小扳手圖示,進入設定頁面找到ssl關掉即可。當然同學們直接使用http://localhost:5000請求就無需設定SSL.

 

 

 

2.請求引數

這裡的引數value就是我們在鑑權服務配置類設定的client和TestUser資訊。

Grant_Type為授權型別,本文我們使用的是使用者密碼模式,所以這裡填password.

 

 

 

這裡我們看到,我們已成功模擬請求獲取了Token。大功告成,鑑權服務已驗證可用,我們趕緊去釋出部署吧。

第六步,鑑權服務釋出部署。

.Net Core釋出模式有三種:

1.框架依賴+可移植

2.框架依賴+執行時環境(帶可執行程式exe)

3.獨立部署

 

簡單來說,框架依賴模式釋出的程式包,都需要部署環境自帶.net core等執行環境;而獨立部署則不需要考慮,釋出包已經包含了執行環境,直接部署即可。

下面本文以框架依賴+可移植髮布,做簡單介紹。

 

 

 

 釋出完成後,我們會在釋出路徑中看到程式dll.我們找到釋出路徑,通過CMD命令視窗:dotnet xxx.dll可直接啟動。

 如上,則表示啟動成功。(如果其他釋出模式,直接雙擊發布包中可執行exe檔案即可啟動)

 

鑑權服務部署完成後,我們API介面如何使用呢,下面開始正式介紹。

第一步:新建Web Api專案

新增Nuget程式包

 

 

第二步:配置啟動類

 1         public void ConfigureServices(IServiceCollection services)
 2         {
 3             //註冊服務
 4             services.AddAuthentication("Bearer")
 5                 .AddIdentityServerAuthentication(x =>
 6                 {
 7                     x.Authority = "http://localhost:5000";//鑑權服務地址
 8                     x.RequireHttpsMetadata = false;
 9                     x.ApiName = "api1";//鑑權範圍
10                 });
11             services.AddControllers();
12         }
13 
14         public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
15         {
16             if (env.IsDevelopment())
17             {
18                 app.UseDeveloperExceptionPage();
19             }
20             app.UseAuthentication();//新增鑑權認證
21             app.UseHttpsRedirection();
22             app.UseRouting();
app.UseAuthorization(); 23 app.UseEndpoints(endpoints => 24 { 25 endpoints.MapControllers(); 26 }); 27 }

應用程式預設的埠號有兩種:1.http://localhost:5000   2.https://localhost:5001.為了避免埠號衝突被佔用,我們可以在Program類中修改應用程式啟動埠號。

1  public static IHostBuilder CreateHostBuilder(string[] args) =>
2             Host.CreateDefaultBuilder(args)
3             
4                 .ConfigureWebHostDefaults(webBuilder =>
5                 {
6                     webBuilder.UseUrls("http://*:5555");//設定啟動埠號
7                     webBuilder.UseStartup<Startup>();
8                 });

 

第三步:建立API  DEMO

 1  [Route("api/[controller]")]
 2     [ApiController]
 3     public class TestController : ControllerBase
 4     {
 5         // GET: api/Test
 6         /// <summary>
 7         /// 方法加權
 8         /// </summary>
 9         /// <returns></returns>
10         [Authorize]
11         [HttpGet]
12         public IEnumerable<string> Get()
13         {
14             return new string[] { "value1", "value2" };
15         }
16 
17         /// <summary>
18         /// 方法未加權  可直接訪問
19         /// </summary>
20         /// <param name="id"></param>
21         /// <returns></returns>
22         // GET: api/Test/5
23         [HttpGet("{id}", Name = "Get")]
24         public string Get(int id)
25         {
26             return "value";
27         }
28 
29         /// <summary>
30         /// 開放獲取token  API 介面
31         /// </summary>
32         /// <returns></returns>
33         [HttpGet("GetToken")]
34         public async Task<string> GetToken()
35         {
36             var client = new HttpClient();
37             var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
38             {
39                 Address = "http://localhost:5000/connect/token",
40                 ClientId = "client",
41                 ClientSecret = "secret",
42                 Scope = "api1",
43                 UserName = "Admin",
44                 Password = "123456",
45             });
46 
47             if (tokenResponse.IsError)
48             {
49                 return tokenResponse.Error;
50             }
51 
52             return tokenResponse.AccessToken;
53 
54         }
55     }

1.介面方法上加上:

[Authorize]

相當於對介面加權,只有被授權的使用者才能訪問(即獲取token的使用者)。此時上文中介面api/Test由於被加權,請求時會報錯;但是api/Test/1介面未加權,仍可正常請求。

那麼我們如何才能訪問被加權的介面呢???Go Next

2.我們這裡開放了獲取Token的介面GetToken(類似於上文中通過PostMan獲取Token)

訪問被加權的API介面,我們這裡需要先請求獲取Token,然後請求加權介面時帶上token引數。

 

 

 3.請求加權介面

 

 請求加權介面時帶上Token,介面請求成功!

 

OK,關於如何快速開發和除錯基於IdentityServer4框架的API介面鑑權服務,至此我們已介紹完畢。

小弟不才,本文中有考慮不周全或錯誤的地方,歡迎大家指正。

(如果有的同學想通過IIS部署API應用程式,這裡有個地方需要注意下,需要在IIS(功能檢視——模組)中新增AspNetCoreModule模組。具體原因本文就不在這裡介紹了。)<