1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        ASP.NET Core 實現(xiàn)基于 ApiKey 的認(rèn)證

        共 4918字,需瀏覽 10分鐘

         ·

        2022-03-16 15:19

        ASP.NET Core 實現(xiàn)基于 ApiKey 的認(rèn)證

        Intro

        之前我們有介紹過實現(xiàn)基于請求頭的認(rèn)證,今天來實現(xiàn)一個基于 ApiKey 的認(rèn)證方式,使用方式參見下面的示例

        Sample

        注冊認(rèn)證服務(wù)

        services.AddAuthentication()
        ????.AddApiKey(options?=>
        ????{
        ????????options.ApiKey?=?"123456";
        ????????options.ApiKeyName?=?"X-ApiKey";
        ????});

        可以根據(jù)需要是否要指定為默認(rèn)的認(rèn)證 Schema

        控制器示例代碼:

        [HttpGet("apiKeyTest")]
        [Authorize(AuthenticationSchemes?=?ApiKeyAuthenticationDefaults.AuthenticationSchema)]
        public?IActionResult?ApiKeyAuthTest()
        {
        ????return?Ok(User.Identity);
        }

        因為我們沒有指定為默認(rèn)的認(rèn)證 Schema,所以在這個 Action 上我們指定了希望使用的認(rèn)證方式

        調(diào)用示例:

        直接調(diào)用不使用 ApiKey

        使用錯誤的 ApiKey

        使用正確的 ApiKey

        從上面的結(jié)果可以看出來只有在 ApiKey 是正確的情況下才能正常調(diào)用 Api

        Implement

        對于自定義認(rèn)證方式我們之前也有介紹過基于請求頭的認(rèn)證方式,基于 ApiKey 的認(rèn)證和請求頭也類似,

        對于自定義認(rèn)證方式,核心需要定義的有兩個類型

        • 一個是認(rèn)證選項,自定義的 AuthenticationOption
        • 一個是認(rèn)證處理器,自定義的認(rèn)證處理邏輯

        下面來看實現(xiàn)

        ApiKeyAuthenticationOptions

        實現(xiàn)如下:

        public?sealed?class?ApiKeyAuthenticationOptions?:?AuthenticationSchemeOptions
        {
        ????public?string?ApiKey?{?get;?set;?}
        ????public?string?ApiKeyName?{?get;?set;?}?=?"X-ApiKey";
        ????public?string?ClientId?{?get;?set;?}
        ????public?KeyLocation?KeyLocation?{?get;?set;?}

        ????public?override?void?Validate()
        ????{
        ????????if?(string.IsNullOrWhiteSpace(ApiKey))
        ????????{
        ????????????throw?new?ArgumentException("Invalid?ApiKey?configured");
        ????????}
        ????}
        }

        public?enum?KeyLocation
        {
        ????Header?=?0,
        ????Query?=?1,
        ????HeaderOrQuery?=?2,
        ????QueryOrHeader?=?3,
        }

        繼承于 AuthenticationSchemeOptions 并添加認(rèn)證所需的配置,我們增加了一個 KeyLocation 以配置讀取 ApiKey 的來源,Header 就是從請求頭去讀,Query 就是從查詢字符串讀取,HeaderOrQuery 就是優(yōu)先讀取 Header,對應(yīng)的 QueryOrHeader 就是優(yōu)先讀取查詢字符串

        另外我們可以重載 Validate 方法來對我們的配置進(jìn)行校驗

        ApiKeyAuthenticationHandler

        認(rèn)證處理器是認(rèn)證方式的核心處理邏輯,我們的處理也比較簡單,就是直接讀取 ApiKey 與配置的 ApiKey 對比,一致就認(rèn)證成功,否則就是非法請求,實現(xiàn)如下:

        public?sealed?class?ApiKeyAuthenticationHandler?:?AuthenticationHandler<ApiKeyAuthenticationOptions>
        {
        ????public?ApiKeyAuthenticationHandler(IOptionsMonitor?options,?ILoggerFactory?logger,?UrlEncoder?encoder,?ISystemClock?clock)?:?base(options,?logger,?encoder,?clock)
        ????{
        ????}

        ????protected?override?Task?HandleAuthenticateAsync()
        ????{
        ????????var?authResult?=?HandleAuthenticateInternal();
        ????????return?Task.FromResult(authResult);
        ????}

        ????private?AuthenticateResult?HandleAuthenticateInternal()
        ????{
        ????????StringValues?keyValues;
        ????????var?keyExists?=?Options.KeyLocation?switch
        ????????{
        ????????????KeyLocation.Query?=>?Request.Query.TryGetValue(Options.ApiKeyName,?out?keyValues),
        ????????????KeyLocation.HeaderOrQuery?=>?Request.Headers.TryGetValue(Options.ApiKeyName,?out?keyValues)?||?Request.Query.TryGetValue(Options.ApiKeyName,?out?keyValues),
        ????????????KeyLocation.QueryOrHeader?=>?Request.Query.TryGetValue(Options.ApiKeyName,?out?keyValues)?||?Request.Headers.TryGetValue(Options.ApiKeyName,?out?keyValues),
        ????????????_?=>?Request.Headers.TryGetValue(Options.ApiKeyName,?out?keyValues),
        ????????};
        ????????if?(!keyExists)
        ????????????return?AuthenticateResult.NoResult();

        ????????if?(keyValues.ToString().Equals(Options.ApiKey))
        ????????{
        ????????????var?clientId?=?Options.ClientId.GetValueOrDefault(ApplicationHelper.ApplicationName);
        ????????????return?AuthenticateResult.Success(
        ????????????????new?AuthenticationTicket(
        ????????????????????new?ClaimsPrincipal(new[]
        ????????????????????{
        ????????????????????????????new?ClaimsIdentity(new[]
        ????????????????????????????{
        ????????????????????????????????new?Claim(nameof(Options.ClientId),?clientId,?ClaimValueTypes.String,?ClaimsIssuer),
        ????????????????????????????},?Scheme.Name)
        ????????????????????}),?Scheme.Name)
        ????????????);
        ????????}
        ????????return?AuthenticateResult.Fail("Invalid?Api-Key");
        ????}
        }

        Extensions

        為了方便使用添加了幾個常用的擴(kuò)展方法,類似于 ASP.NET Core 自帶的認(rèn)證方式

        首先增加了一個默認(rèn)的認(rèn)證模式

        public?static?class?ApiKeyAuthenticationDefaults
        {
        ????public?const?string?AuthenticationSchema?=?"ApiKey";
        }

        然后增加了一些依賴注入的擴(kuò)展

        public?static?AuthenticationBuilder?AddApiKey(this?AuthenticationBuilder?builder)
        {
        ????return?builder.AddApiKey(ApiKeyAuthenticationDefaults.AuthenticationSchema);
        }

        public?static?AuthenticationBuilder?AddApiKey(this?AuthenticationBuilder?builder,?string?schema)
        {
        ????return?builder.AddApiKey(schema,?_?=>?{?});
        }

        public?static?AuthenticationBuilder?AddApiKey(this?AuthenticationBuilder?builder,
        ????Action?configureOptions
        )

        {
        ????return?builder.AddApiKey(ApiKeyAuthenticationDefaults.AuthenticationSchema,
        ????????configureOptions);
        }

        public?static?AuthenticationBuilder?AddApiKey(this?AuthenticationBuilder?builder,?string?schema,
        ????Action?configureOptions
        )

        {
        ????if?(null?!=?configureOptions)
        ????{
        ????????builder.Services.Configure(configureOptions);
        ????}
        ????return?builder.AddScheme(schema,
        ????????configureOptions);
        }

        More

        目前的實現(xiàn)比較簡單,只是對 ApiKey 做了校驗,而且是直接讀取的配置,大家可以根據(jù)自己需要進(jìn)行一定的擴(kuò)展,比如 ApiKey 從數(shù)據(jù)庫中讀取、增加額外的 claim 配置等。

        對于一些需要配置客戶端訪問權(quán)限的可以使用這種方式來實現(xiàn)簡單的認(rèn)證來代替基于 OAuth 的 Client Credentials?方式,相對來說會簡單一些

        References

        • https://github.com/WeihanLi/WeihanLi.Web.Extensions/blob/dev/src/WeihanLi.Web.Extensions/Authentication/ApiKeyAuthentication/ApiKeyAuthenticationHandler.cs
        • https://github.com/WeihanLi/WeihanLi.Web.Extensions/blob/dev/samples/WeihanLi.Web.Extensions.Samples/Program.cs
        • asp.net core 自定義認(rèn)證方式--請求頭認(rèn)證


        瀏覽 67
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            人人摸人人操人人搞 | 孕妇H圆房~H嗯啊呻吟视频 | 国产操吧| 人善交video另类hd侏儒 | 少妇精品偷拍高潮 | 亚洲国产精品动漫 | 国产网红女主播精品视频 | 久久国产精品无码挤奶水一区 | 天天综合网欧美 | 中国一级淫片bbb |