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的方式。 這裏特別感謝張隊的耐心指導!html

爲何使用IdentityServer4?

上一篇文章中,給你們講解了如何經過 Asp.Net Core Web Api實現圖片上傳的接口,具體的能夠[點這裏查看][http://www.javashuo.com/article/p-zrjibmdm-n.html] 。這個接口是一個公開的接口,如何發佈的話,任何知道調用方法的"任何人"都能任意的調用這個接口,俗稱「裸奔」。這時候咱們就應該給接口加入認證以及訪問控制機制,來增強安全性!那麼咱們怎麼來實現接口的認證以及訪問控制呢?這時候部分人就會很懵逼了,還有一部分人就會聯想到 OpenID Connect 和 OAuth 2.0了!但是怎麼實現呢?從到到位搭一個這樣的框架,會累死我滴,可能還要通過很長時間的測試呢!別擔憂,這時候就體現出Asp.Net Core社區的強大了,咱們的主角IdentityServer4閃亮登場!git

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/] 。想了解更多自行閱讀官方文檔吧!github

爲了演示的方便,本文采用的是客戶端認證模式,至於其餘的幾種驗證模式,你們能夠看下上面給出的阮一峯的文章。還有你們用以前要理解下身份認證服務器(IdentityServer),用戶(User),客戶端(Client),資源(Resources),身份令牌(Identity Token),訪問令牌(Access Token)這些概念。若是不清楚的話能夠參考曉晨Master的這篇「ASP.NET Core的身份認證框架IdentityServer4(3)-術語的解釋」文章。web

Asp.Net Core Web Api中如何使用IdentityServer4呢?

建立IdentityServer4服務端即「身份認證服務器(IdentityServer)」

  1. 新建一個空的Asp.Net Core Web Api項目,名稱爲IdentityServer端口爲5001,以下圖所示json

    IdentityServer

  2. 經過Nuget安裝IdentityServer4命令以下,記得程序包管理控制套,上面的項目選擇剛剛建立的IdentityServer項目c#

    Install-Package IdentityServer4 

安裝IdentityServer4

  1. 這裏由於採用OAuth 2.0的客戶端模式,因此簡單地使用一個類來硬編碼一些資源(Resources)

以及客戶端(Client),代碼以下:api

/// <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安全認證明例教程到此結束了。

示例代碼

[點我下載][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說明文檔看這篇就夠了][http://www.javashuo.com/article/p-xlcnpzoq-gy.html] 。這個系列的教程源碼,我已經放在github上了,你們能夠點這裏進行訪問源代碼。https://github.com/yilezhu/ImageUploadApiDemo

相關文章
相關標籤/搜索