寫在前面 本文地址:http://www.cnblogs.com/yilezhu/p/9315644.html 作者:yilezhu 上一篇關於Asp.Net Core Web Api圖片上傳的文章使用的是mongoDB進行圖片的存儲,文章發佈後,張隊就來了一句,說沒有使用GridFS。的確博主只是 ...
寫在前面
本文地址:http://www.cnblogs.com/yilezhu/p/9315644.html
作者:yilezhu
上一篇關於Asp.Net Core Web Api圖片上傳的文章使用的是mongoDB進行圖片的存儲,文章發佈後,張隊就來了一句,說沒有使用GridFS。的確博主只是進行了簡單的圖片上傳以及mongoDB存儲操作,目的是提供思路。具體的圖片存儲,有條件的還是基於阿裡雲OSS或者七牛吧,如果實在想用MongDB進行存儲的話,建議採用GridFS的方式!
又有人說,GridFS大於16M的時候才適合使用,圖片上傳已經控制小於1M了,就沒必要使用GridFS了吧。這裡可以指定chunksize的大小。這樣性能上就沒有什麼問題了。而且在性能差不多的時候使用GridFS可以更方便的管理。因此建議如果採用MongDB進行文件存儲的話,建議採用GridFS的方式。 這裡特別感謝張隊的耐心指導!
為什麼使用IdentityServer4?
上一篇文章中,給大家講解瞭如何通過 Asp.Net Core Web Api實現圖片上傳的介面,具體的可以[點這裡查看][https://www.cnblogs.com/yilezhu/p/9297009.html] 。這個介面是一個公開的介面,如何發佈的話,任何知道調用方法的"任何人"都能任意的調用這個介面,俗稱“裸奔”。這時候我們就應該給介面加入認證以及訪問控制機制,來加強安全性!那麼我們怎麼來實現介面的認證以及訪問控制呢?這時候部分人就會很懵逼了,還有一部分人就會聯想到 OpenID Connect 和 OAuth 2.0了!可是怎麼實現呢?從到到位搭一個這樣的框架,會累死我滴,可能還要經過很長時間的測試呢!別擔心,這時候就體現出Asp.Net Core社區的強大了,我們的主角IdentityServer4閃亮登場!
IdentityServer4是什麼?能幫我們做什麼呢?
IdentityServer4是一套為 ASP.NET Core 2.0開發的基於OpenID Connect 和 OAuth 2.0 的框架,他能讓我們的系統很輕鬆的就能很多認證以及授權相關的功能,比如:單點登錄,api訪問控制等等!其他的我就不介紹了,社區裡面介紹的太多太多了!如果有想瞭解的OAuth 2.0的可以看看阮一峰的這篇文章[理解OAuth 2.0][http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html] 。最後 IdentityServer4最最最大好處是開源的,用的人也多,而且比較成熟。想想是不是有點小激動,迫不及待的想試試了。在開始之前,附上[開原地址][https://github.com/IdentityServer/IdentityServer4] 以及[詳細文檔][https://identityserver4.readthedocs.io/en/release/] 。想瞭解更多自行閱讀官方文檔吧!
為了演示的方便,本文采用的是客戶端認證模式,至於其他的幾種驗證模式,大家可以看下上面給出的阮一峰的文章。還有大家用之前要理解下身份認證伺服器(IdentityServer),用戶(User),客戶端(Client),資源(Resources),身份令牌(Identity Token),訪問令牌(Access Token)這些概念。如果不清楚的話可以參考曉晨Master的這篇“ASP.NET Core的身份認證框架IdentityServer4(3)-術語的解釋”文章。
Asp.Net Core Web Api中如何使用IdentityServer4呢?
創建IdentityServer4服務端即“身份認證伺服器(IdentityServer)”
新建一個空的Asp.Net Core Web Api項目,名稱為IdentityServer埠為5001,如下圖所示
通過Nuget安裝IdentityServer4命令如下,記得程式包管理控制套,上面的項目選擇剛剛創建的IdentityServer項目
Install-Package IdentityServer4
- 這裡因為採用OAuth 2.0的客戶端模式,所以簡單地使用一個類來硬編碼一些資源(Resources)
以及客戶端(Client),代碼如下:
/// <summary>
/// yilezhu
/// 2018.7.15
/// 因為此處採用in-memory,所以硬編碼一些api,以及client
/// </summary>
public class ApiConfig
{
/// <summary>
/// 定義ApiResource 這裡的資源(Resources)指的就是我們的API
/// </summary>
/// <returns>ApiResource枚舉</returns>
public static IEnumerable<ApiResource> GetApiResources()
{
return new[]
{
new ApiResource("PictureApi", "圖片上傳的APi")
};
}
/// <summary>
/// 定義受信任的客戶端 Client
/// </summary>
/// <returns></returns>
public static IEnumerable<Client> GetClients()
{
return new[]
{
new Client
{
ClientId = "MobileUploadPicture",//客戶端的標識,要是惟一的
ClientSecrets = new [] { new Secret("yilezhu123".Sha256()) },//客戶端密碼,進行了加密
AllowedGrantTypes = GrantTypes.ClientCredentials,//授權方式,這裡採用的是客戶端認證模式,只要ClientId,以及ClientSecrets正確即可訪問對應的AllowedScopes裡面的api資源
AllowedScopes = new [] { "PictureApi" }//定義這個客戶端可以訪問的APi資源數組,上面只有一個api
}
};
}
}
在Startup.cs中註入IdentityServer服務並使用中間件,代碼如下:
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { //註入IdentityServer服務 services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryClients(ApiConfig.GetClients()) .AddInMemoryApiResources(ApiConfig.GetApiResources()); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } //添加認證中間件 app.UseIdentityServer(); app.UseMvc(); }
用Postman測試並獲取AccessToken吧!如下圖所示,在Post請求中傳入,認證類型,client_id以及client_secret即可獲取AccessToken:
當傳入錯誤的Client_id或者密碼將出現下麵的結果
- 至此IdentityServer服務已經簡單地完成了!下麵改造下我們的圖片上傳服務。
改造圖片上傳介面,加入授權認證
在圖片上傳api項目中添加IdentityServer nuget包,這裡只需要加入AccessTokenValidation包即可,註意選擇api項目:
Install-Package IdentityServer4.AccessTokenValidation
appsettings.json中加入IdentityServerOptions,進行IdentityServer的一些配置
"IdentityServerOptions": {
"ServerIP": "localhost",
"ServerPort": 5001,
"IdentityScheme": "Bearer",
"ResourceName": "PictureApi"
}
新建一個類用來匹配這個options,這樣可以爽爽的使用:
/// <summary> /// yilezhu /// 2018.7.15 /// IdentityServer的配置選項 /// </summary> public class IdentityServerOptions { /// <summary> /// 授權伺服器的Ip地址 /// </summary> public string ServerIP { get; set; } /// <summary> /// 授權伺服器的埠號 /// </summary> public int ServerPort { get; set; } /// <summary> /// access_token的類型,獲取access_token的時候返回參數中的token_type一致 /// </summary> public string IdentityScheme { get; set; } /// <summary> /// 資源名稱,認證服務註冊的資源列表名稱一致, /// </summary> public string ResourceName { get; set; } }
在Startup.cs中加入identityServer驗證
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//註入Options
OptionsConfigure(services);
var identityServerOptions = new IdentityServerOptions();
Configuration.Bind("IdentityServerOptions", identityServerOptions);
services.AddAuthentication(identityServerOptions.IdentityScheme)
.AddIdentityServerAuthentication(options =>
{
options.RequireHttpsMetadata = false; //是否啟用https
options.Authority = $"http://{identityServerOptions.ServerIP}:{identityServerOptions.ServerPort}";//配置授權認證的地址
options.ApiName = identityServerOptions.ResourceName; //資源名稱,跟認證服務中註冊的資源列表名稱中的apiResource一致
}
);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
}
/// <summary>
/// yilezhu
/// 2018.7.10
/// 註冊Options
/// </summary>
/// <param name="services">服務容器</param>
private void OptionsConfigure(IServiceCollection services)
{
//MongodbHost信息
services.Configure<MongodbHostOptions>(Configuration.GetSection("MongodbHost"));
//圖片選項
services.Configure<PictureOptions>(Configuration.GetSection("PictureOptions"));
}
為需要說全訪問的圖片上傳介面添加[Authorize]特性,當然要引用下命名空間:
using Microsoft.AspNetCore.Authorization;
/// <summary> /// 介面上傳圖片方法 /// </summary> /// <param name="fileDtos">文件傳輸對象,傳過來的json數據</param> /// <returns>上傳結果</returns> [HttpPost] [Authorize] public async Task<UploadResult> Post([FromBody] FileDtos fileDtos) { ………… }
把授權服務以及圖片上傳介面同時啟動下,然後Postman再次進行下圖片上傳的測試:
在請求頭上加入我們獲取的token信息,來再次訪問下:
Asp.Net Core Web Api圖片上傳介面集成Identity Server 4安全認證實例教程到此結束了。
示例代碼
[點我下載][https://github.com/yilezhu/ImageUploadApiDemo]
總結
本文通過圖片上傳這個Asp.Net Core Web Api做引子,然後引入Identity Server 4。然後通過一個簡單地實例教程闡述瞭如何創建Identity Server 以及介面中如何進行授權認證訪問。博主儘量採用通俗易懂的語言進行闡述,步驟也儘量詳細,目的就是為了讓初學者也能按照步驟一步一步的實現Identity Server 4的認證。下一篇我會加入SwaggerUI生成介面文檔,當然大家也可以看下我的這篇關於SwaggerUI的文章[ASP.NET Core WebApi使用Swagger生成api說明文檔看這篇就夠了][https://www.cnblogs.com/yilezhu/p/9241261.html] 。這個系列的教程源碼,我已經放在github上了,大家可以點這裡進行訪問源代碼。https://github.com/yilezhu/ImageUploadApiDemo