1. 程式人生 > >Asp.NetCoreWebApi圖片上傳介面(二)整合IdentityServer4授權訪問(附原始碼)

Asp.NetCoreWebApi圖片上傳介面(二)整合IdentityServer4授權訪問(附原始碼)

寫在前面

本文地址: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)”

  1. 新建一個空的Asp.Net Core Web Api專案,名稱為IdentityServer埠為5001,如下圖所示

    IdentityServer

  2. 通過Nuget安裝IdentityServer4命令如下,記得程式包管理控制套,上面的專案選擇剛剛建立的IdentityServer專案

    Install-Package IdentityServer4 

安裝IdentityServer4

  1. 這裡因為採用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
                }
            };
        }
    }
  1. 在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();
            }
  2. 用Postman測試並獲取AccessToken吧!如下圖所示,在Post請求中傳入,認證型別,client_id以及client_secret即可獲取AccessToken:

成功獲取Access_Token

當傳入錯誤的Client_id或者密碼將出現下面的結果

錯誤的密碼,獲取不到

  1. 至此IdentityServer服務已經簡單地完成了!下面改造下我們的圖片上傳服務。

改造圖片上傳介面,加入授權認證

  1. 在圖片上傳api專案中新增IdentityServer nuget包,這裡只需要加入AccessTokenValidation包即可,注意選擇api專案:

    Install-Package IdentityServer4.AccessTokenValidation

    安裝AccessTokenValidation

  2. appsettings.json中加入IdentityServerOptions,進行IdentityServer的一些配置

"IdentityServerOptions": {

    "ServerIP": "localhost",
    "ServerPort": 5001,
    "IdentityScheme": "Bearer",
    "ResourceName": "PictureApi"
  }
  1. 新建一個類用來匹配這個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; }
        }
  2. 在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"));

        }
  1. 為需要說全訪問的圖片上傳介面新增[Authorize]特性,當然要引用下名稱空間:

    using Microsoft.AspNetCore.Authorization;
     /// <summary>
            /// 介面上傳圖片方法
            /// </summary>
            /// <param name="fileDtos">檔案傳輸物件,傳過來的json資料</param>
            /// <returns>上傳結果</returns>
            [HttpPost]
            [Authorize]
            public async Task<UploadResult> Post([FromBody] FileDtos fileDtos)
            {
                …………
            }
    
  2. 把授權服務以及圖片上傳介面同時啟動下,然後Postman再次進行下圖片上傳的測試:

    多專案啟動

    返回結果,未授權

  3. 在請求頭上加入我們獲取的token資訊,來再次訪問下:

    加入驗證頭

    訪問成功

  4. Asp.Net Core Web Api圖片上傳介面整合Identity Server 4安全認證例項教程到此結束了。

示例程式碼

總結

本文通過圖片上傳這個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