ASP.NET Core 实现基于 ApiKey 的认证

ASP.NET Core 实现基于 ApiKey 的认证

Intro

之前我们有介绍过实现基于请求头的认证,今天来实现一个基于 ApiKey 的认证方式,使用方式参见下面的示例

Sample

注册认证服务

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

可以根据需要是否要指定为默认的认证 Schema

控制器示例代码:

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

因为我们没有指定为默认的认证 Schema,所以在这个 Action 上我们指定了希望使用的认证方式

调用示例:

直接调用不使用 ApiKey

df05984a12a56ef0776c98767fcf8cba.png

使用错误的 ApiKey

bf98f2eff1731f81309feca87ba4a2ce.png

使用正确的 ApiKey

0aafb15ce4fe32b5cf62d49f9df76159.png

从上面的结果可以看出来只有在 ApiKey 是正确的情况下才能正常调用 Api

Implement

对于自定义认证方式我们之前也有介绍过基于请求头的认证方式,基于 ApiKey 的认证和请求头也类似,

对于自定义认证方式,核心需要定义的有两个类型

  • 一个是认证选项,自定义的 AuthenticationOption

  • 一个是认证处理器,自定义的认证处理逻辑

下面来看实现

ApiKeyAuthenticationOptions

实现如下:

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 并添加认证所需的配置,我们增加了一个 KeyLocation 以配置读取 ApiKey 的来源,Header 就是从请求头去读,Query 就是从查询字符串读取,HeaderOrQuery 就是优先读取 Header,对应的 QueryOrHeader 就是优先读取查询字符串

另外我们可以重载 Validate 方法来对我们的配置进行校验

ApiKeyAuthenticationHandler

认证处理器是认证方式的核心处理逻辑,我们的处理也比较简单,就是直接读取 ApiKey 与配置的 ApiKey 对比,一致就认证成功,否则就是非法请求,实现如下:

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

为了方便使用添加了几个常用的扩展方法,类似于 ASP.NET Core 自带的认证方式

首先增加了一个默认的认证模式

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

然后增加了一些依赖注入的扩展

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

目前的实现比较简单,只是对 ApiKey 做了校验,而且是直接读取的配置,大家可以根据自己需要进行一定的扩展,比如 ApiKey 从数据库中读取、增加额外的 claim 配置等。

对于一些需要配置客户端访问权限的可以使用这种方式来实现简单的认证来代替基于 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 自定义认证方式--请求头认证

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/290789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android之调用系统分享

1、调用系统分享关键代码 private void shareImage() {Intent intent = new Intent(Intent.ACTION_SEND); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File("sdcard/screenshot.png")));intent.setTyp…

hdu4750Count The Pairs(最小生成树找瓶颈边)

1 /*2 题意&#xff1a;就是给你一个图&#xff0c;图的每两个点都有多条路径&#xff0c;每一条路径中都有一条最大边&#xff0c;3 所有最大边的最小边&#xff08;也就是瓶颈边&#xff09;就是这两点之间的val值&#xff01;然后给你一个值f&#xff0c;4 问有多少…

服务器的响应一直一直发送不过去,zeroRPC:在发送响应后继续运行进程

我使用Python2.7和zeroRPC使客户机和服务器通信。我希望客户端向服务器发送一个请求&#xff0c;我希望服务器发送一个响应以确认它已收到请求。但是我希望服务器对该请求执行一些繁重的计算。这些计算将花费数小时&#xff0c;并且不会产生任何响应&#xff0c;因此客户机不应…

白平衡自己主动(AWB)算法---2,颜色计算

本文说明了白平衡算法估计当前场景的色温过程. 色温计算的原理并不复杂,但要做到,还是一道&#xff0c;认真做好每一步,这需要大量的测试,和算法一直完好. 关于该过程首先简要: 1, 取的图像数据,并划分MxN块,如果是25x25,并统计每一块的基本信息(,白色像素的数量及R/G/B通道的分…

【机房收费系统】多么痛的领悟

这次机房收费系统&#xff0c;是全部的项目中&#xff0c;自己完毕的最不惬意的了。 时间之长。效率之慢。一開始。就感觉无从下手&#xff0c;但总会相信自己能慢慢的进入状态。最终有机会自己练练手了。也自觉得之前自己设计模式学的还不错。也最终有机会能自己想想设计模式了…

linux(windows)之svn重定向地址

1、问题 svn下载的项目路径需要换&#xff0c;也就是下面的URL:SVN:// 需要修改 2、解决办法 linux平台 svn switch --relocate oldSvnPath newSvnPath windows平台 右击项目 TortoiseSVN->Relocate 然后修改就行

简单的邮箱格式校验方式

简单的邮箱格式校验方式Intro前段时间有一个验证邮箱格式的小需求&#xff0c;然后突然发现了一种非常简单的邮箱格式判断方式Implement直接来看实现public static bool IsEmailAddress(string email) {if (string.IsNullOrWhiteSpace(email))return false;var symbolIndex em…

Ubuntu14.04LST安装weblogic11g

1:下载链接http://download.oracle.com/otn/nt/middleware/11g/wls/1036/wls1036_generic.jar 2:进行安装&#xff08;前提已经安装好JDK&#xff09; yy:~/my_download$ java -d64 -Xmx1024m -jar wls1036_generic.jar Extracting 0%.......................................…

服务器连接不稳定fifa,fifa服务器链接异常

fifa服务器链接异常 内容精选换一换获取登录密码Windows操作系统在创建时只能选择密钥登录&#xff0c;需要先将密钥文件解析为密码&#xff0c;参考链接&#xff1a;获取Windows裸金属服务器的密码Windows操作系统在创建时只能选择密钥登录&#xff0c;需要先将密钥文件解析为…

并发编程总结4-JUC-REENTRANTLOCK-2(公平锁)

内容包括&#xff1a;1、ReentrantLock函数分析2、ReentrantLock公平锁源码&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#…

Android之项目全部能正常登录但是部分资源没有显示成功的解决办法

1、问题 自己写的项目&#xff0c;PC端没有问题&#xff0c;移动端有问题 第一个问题 部分能登录&#xff0c;一部分不能登录 第二个问题 解决第一个问题后&#xff0c;全部能登录&#xff0c;但是登录之后部分资源显示不成功&#xff0c;部分可以 2、原因 第一个问题的原…

ASP.NET Core 6 的性能改进

受到 由Stephen Toub 发布的关于 .NET 性能的博客的启发&#xff0c;我们正在写一篇类似的文章来强调ASP.NET Core 在6.0 中所做的性能改进。基准设置我们整个过程中大部分的实例使用的是BenchmarkDotNet。在此链接上提供了repo&#xff0c;其中包括本文中使用的大多数基准。Be…

(转载)在服务器上排除问题的头5分钟

尽可能搞清楚问题的前因后果 不要一下子就扎到服务器前面&#xff0c;你需要先搞明白这台服务器有多少已知的情况&#xff0c;还有故障的具体情况&#xff0c;不然你很有可能是在无的放矢必须要搞清楚的问题&#xff1a;故障的表现是什么&#xff1f;无响应&#xff1f;报错&am…

wikioi 1034 家 实时动态的网络流量(费用流)

因为随着时间的推移。网络侧变得&#xff0c;因此&#xff0c;常见的网络流量也解决不了这个问题&#xff0c;。如果T毕竟运输时间。为此。我们可以基于时间分割点&#xff0c;所有的点将被分割为T点。 对于每一个点&#xff0c;下一次甚至一个容量为本人INF边缘&#xff0c;费…

华为服务器只显示一个下划线,华为官方解释:为什么鸿蒙系统logo下面会有一条下划线...

HarmonyOS 的 Logo 中为什么有一横&#xff1f;为什么这一横偏偏是蓝色&#xff1f;HarmonyOS 的字体设计又藏着什么奥秘&#xff1f;6月10日晚&#xff0c;华为官方微博对鸿蒙系统LOGO设计寓意&#xff0c;作出了官方科普。下面就来为你一一解答在现代汉语中“旦”字与鸿蒙OS中…

Android之jni出现JNIEnv has no member named ‘GetMehtodID‘解决办法

1、问题 ndk-build提示 JNIEnv has no member named GetMehtodID 2、原因 我把那个函数写错了 3、解决办法 复制上面正常的函数&#xff0c;把函数改为 env->GetMethodID

ORACLE利用STANDBY端RMAN备份进行数据恢复

这里记录一下流程&#xff0c;有我和同事问心进行测试 dataguard主库和物理备库主要是controlfile文件有区别&#xff0c;用restore可以查看含有primary,standby关键字 RMAN> restore ; RMAN-00571: RMAN-00569: ERROR MESSAGE STACK FOLLOWS RMAN-00571: RMAN-00558: e…

腾讯急招多名.NET Core,5年30k!

金三银四跳槽季&#xff0c;腾讯急招5年左右.NET Core高级开发岗&#xff0c;基本月薪能到30k&#xff0c;心动吗&#xff1f;这里推荐个.NET跳槽大厂交流群&#xff0c;有技术交流&#xff0c;有面经分享&#xff0c;还有内推通道&#xff0c;据说有一定几率降低学历要求&…

【BZOJ】1679: [Usaco2005 Jan]Moo Volume 牛的呼声(数学)

http://www.lydsy.com/JudgeOnline/problem.php?id1679 水题没啥好说的。。自己用笔画画就懂了 将点排序&#xff0c;然后每一次的点到后边点的声音距离和(n-i)*(a[i1]-a[i])之前同样操作所得的的sum 然后答案就是累加后2 #include <cstdio> #include <cstring> #…

perl学习笔记——目录操作

在目录书中移动 chdir 操作副改变当前的工作目录。它和shell中cd命令类似&#xff1a; chdir ‘/etc’ or die “cannot chdir to /etc:$1”; 注意&#xff1a;工作目录不能更改的&#xff0c;也就是说Perl程序返回后一定会回到所在的工作目录。 如果调用chdir时不加参数&#…