ASP.NET Core 实现基于 ApiKey 的认证
ASP.NET Core 實(shí)現(xiàn)基于 ApiKey 的認(rèn)證
Intro
之前我們有介紹過(guò)實(shí)現(xiàn)基于請(qǐng)求頭的認(rèn)證,今天來(lái)實(shí)現(xiàn)一個(gè)基于 ApiKey 的認(rèn)證方式,使用方式參見(jiàn)下面的示例
Sample
注冊(cè)認(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); }因?yàn)槲覀儧](méi)有指定為默認(rèn)的認(rèn)證 Schema,所以在這個(gè) Action 上我們指定了希望使用的認(rèn)證方式
調(diào)用示例:
直接調(diào)用不使用 ApiKey
使用錯(cuò)誤的 ApiKey
使用正確的 ApiKey
從上面的結(jié)果可以看出來(lái)只有在 ApiKey 是正確的情況下才能正常調(diào)用 Api
Implement
對(duì)于自定義認(rèn)證方式我們之前也有介紹過(guò)基于請(qǐng)求頭的認(rèn)證方式,基于 ApiKey 的認(rèn)證和請(qǐng)求頭也類似,
對(duì)于自定義認(rèn)證方式,核心需要定義的有兩個(gè)類型
一個(gè)是認(rèn)證選項(xiàng),自定義的 AuthenticationOption
一個(gè)是認(rèn)證處理器,自定義的認(rèn)證處理邏輯
下面來(lái)看實(shí)現(xiàn)
ApiKeyAuthenticationOptions
實(shí)現(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)證所需的配置,我們?cè)黾恿艘粋€(gè) KeyLocation 以配置讀取 ApiKey 的來(lái)源,Header 就是從請(qǐng)求頭去讀,Query 就是從查詢字符串讀取,HeaderOrQuery 就是優(yōu)先讀取 Header,對(duì)應(yīng)的 QueryOrHeader 就是優(yōu)先讀取查詢字符串
另外我們可以重載 Validate 方法來(lái)對(duì)我們的配置進(jìn)行校驗(yàn)
ApiKeyAuthenticationHandler
認(rèn)證處理器是認(rèn)證方式的核心處理邏輯,我們的處理也比較簡(jiǎn)單,就是直接讀取 ApiKey 與配置的 ApiKey 對(duì)比,一致就認(rèn)證成功,否則就是非法請(qǐng)求,實(shí)現(xiàn)如下:
public?sealed?class?ApiKeyAuthenticationHandler?:?AuthenticationHandler<ApiKeyAuthenticationOptions> {public?ApiKeyAuthenticationHandler(IOptionsMonitor<ApiKeyAuthenticationOptions>?options,?ILoggerFactory?logger,?UrlEncoder?encoder,?ISystemClock?clock)?:?base(options,?logger,?encoder,?clock){}protected?override?Task<AuthenticateResult>?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
為了方便使用添加了幾個(gè)常用的擴(kuò)展方法,類似于 ASP.NET Core 自帶的認(rèn)證方式
首先增加了一個(gè)默認(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<ApiKeyAuthenticationOptions>?configureOptions) {return?builder.AddApiKey(ApiKeyAuthenticationDefaults.AuthenticationSchema,configureOptions); }public?static?AuthenticationBuilder?AddApiKey(this?AuthenticationBuilder?builder,?string?schema,Action<ApiKeyAuthenticationOptions>?configureOptions) {if?(null?!=?configureOptions){builder.Services.Configure(configureOptions);}return?builder.AddScheme<ApiKeyAuthenticationOptions,?ApiKeyAuthenticationHandler>(schema,configureOptions); }More
目前的實(shí)現(xiàn)比較簡(jiǎn)單,只是對(duì) ApiKey 做了校驗(yàn),而且是直接讀取的配置,大家可以根據(jù)自己需要進(jìn)行一定的擴(kuò)展,比如 ApiKey 從數(shù)據(jù)庫(kù)中讀取、增加額外的 claim 配置等。
對(duì)于一些需要配置客戶端訪問(wèn)權(quán)限的可以使用這種方式來(lái)實(shí)現(xiàn)簡(jiǎn)單的認(rèn)證來(lái)代替基于 OAuth 的 Client Credentials?方式,相對(duì)來(lái)說(shuō)會(huì)簡(jiǎn)單一些
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)證方式--請(qǐng)求頭認(rèn)證
總結(jié)
以上是生活随笔為你收集整理的ASP.NET Core 实现基于 ApiKey 的认证的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Avalonia跨平台入门第八篇之控件的
- 下一篇: 腾讯急招多名.NET Core,5年30