关键词:
【中文标题】ASP.NET Core 5.0 WebAPI 中的多种身份验证方案【英文标题】:Multiple authentication schemes in ASP.NET Core 5.0 WebAPI 【发布时间】:2022-01-04 08:19:03 【问题描述】:我有一整套在 .NET 5.0 中开发的 (ASP.NET Core) Web API,并实现了 Cookie 和 OpenIdConnect 身份验证方案。 使用 Azure AD 成功验证(用户 ID 和密码)后,会生成 cookie 并存储用户权限等。
现在,我想使用基于 API 密钥的身份验证(通过请求标头中的 api-key)向第三方消费者公开同一组 API。 我开发了一个自定义身份验证处理程序,如下所示。
using Microsoft.AspNetCore.Authentication;
namespace Management.Deployment.Securities.Authentication
public class ApiKeyAuthenticationSchemeOptions : AuthenticationSchemeOptions
namespace Management.Deployment.Securities.Authentication
public static class ApiKeyAuthenticationDefaults
public static readonly string AuthenticationScheme = "ApiKey";
public static readonly string DisplayName = "ApiKey Authentication Scheme";
ApiKeyAuthenticationHandler 定义如下,直截了当,如果请求标头包含有效的 api 密钥,则添加权限声明(分配给 api 密钥)并将身份验证标记为成功,否则失败。
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Management.Securities.Authorization;
using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
namespace Management.Deployment.Securities.Authentication
public class ApiKeyAuthenticationHandler : AuthenticationHandler<ApiKeyAuthenticationSchemeOptions>
private const string APIKEY_NAME = "x-api-key";
private const string APIKEY_VALUE = "sdflasuowerposaddfsadf1121234kjdsflkj";
public ApiKeyAuthenticationHandler(IOptionsMonitor<ApiKeyAuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock) : base(options, logger, encoder, clock)
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
string extractedApiKey = Request.Headers[APIKEY_NAME];
if (!APIKEY_VALUE.Equals(extractedApiKey))
return Task.FromResult(AuthenticateResult.Fail("Unauthorized client."));
var claims = new[]
new Claim("Permissions", "23")
;
var claimsIdentity = new ClaimsIdentity(claims, nameof(ApiKeyAuthenticationHandler));
var authenticationTicket = new AuthenticationTicket(new ClaimsPrincipal(claimsIdentity), Scheme.Name);
return Task.FromResult(AuthenticateResult.Success(authenticationTicket));
我还定义了 ApiKeyAuthenticationExtensions 如下。
using Microsoft.AspNetCore.Authentication;
using Management.Deployment.Securities.Authentication;
using System;
namespace Microsoft.Extensions.DependencyInjection
public static class ApiKeyAuthenticationExtensions
public static AuthenticationBuilder AddApiKey(this AuthenticationBuilder builder)
return builder.AddScheme<ApiKeyAuthenticationSchemeOptions, ApiKeyAuthenticationHandler>(ApiKeyAuthenticationDefaults.AuthenticationScheme, ApiKeyAuthenticationDefaults.DisplayName, x => );
public static AuthenticationBuilder AddApiKey(this AuthenticationBuilder builder, Action<ApiKeyAuthenticationSchemeOptions> configureOptions)
return builder.AddScheme<ApiKeyAuthenticationSchemeOptions, ApiKeyAuthenticationHandler>(ApiKeyAuthenticationDefaults.AuthenticationScheme, ApiKeyAuthenticationDefaults.DisplayName, configureOptions);
Startup.cs 中 ConfigureServices() 的略读版本在这里。请注意我使用了 ForwardDefaultSelector。
public void ConfigureServices(IServiceCollection services)
IAuthCookieValidate cookieEvent = new AuthCookieValidate();
services.AddAuthentication(options =>
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
options.Cookie.Name = ".Mgnt.AspNetCore.Cookies";
options.ExpireTimeSpan = TimeSpan.FromDays(1);
options.Events = new CookieAuthenticationEvents
OnRedirectToAccessDenied = context =>
context.Response.StatusCode = 403;
return Task.FromResult(0);
,
OnRedirectToLogin = context =>
context.Response.StatusCode = 401;
return Task.FromResult(0);
,
OnValidatePrincipal = cookieEvent.ValidateAsync
;
options.ForwardDefaultSelector = context =>
return context.Request.Headers.ContainsKey(ApiConstants.APIKEY_NAME) ? ApiKeyAuthenticationDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme;
;
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options => Configuration.Bind(OpenIdConnectDefaults.AuthenticationScheme, options))
.AddApiKey();
services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
);
services.AddSingleton<IAuthorizationPolicyProvider, AuthorizationPolicyProvider>();
services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
配置方法如下。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseHsts();
app.Use((context, next) =>
context.Request.Scheme = "https";
return next();
);
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
endpoints.MapControllers();
);
当我在请求标头中发送正确的 apikey 时,自定义处理程序将返回成功作为身份验证结果,并进一步处理请求。
但如果传递了错误的 api 密钥,它不会返回身份验证失败消息 - “未经授权的客户端。”。而是进一步处理请求并发送附加的响应。
为解决此问题需要进行哪些更改,以便 api 返回身份验证失败消息 - “未经授权的客户端”。并停止进一步处理请求?
【问题讨论】:
【参考方案1】:如果您打算使用 apikeys,那么您只能靠自己,并且(据我所知)没有内置的对 API-keys 的直接支持。但是,内置了对基于 JWT 的访问令牌的支持,我建议您也将它用于想要访问您的 api 的外部第三方。也许使用客户端凭据流。
如需帮助,请参阅http://codingsonata.com/secure-asp-net-core-web-api-using-api-key-authentication/
我还认为您应该配置并让授权处理程序负责决定谁可以访问服务。
见Policy-based authorization in ASP.NET Core
【讨论】:
我已经用实施细节更新了我的问题。请看一看。 查看我的更新答案即使在 asp.net core 5.0 中提供了不记名令牌,也会返回 401 [关闭]
...】:2021-04-2109:01:11【问题描述】:所以我正在尝试为我的webapi应用程序设置身份验证。现在我只是在乱搞并试图让我的授权端点工作承载令牌,但即使使用令牌我仍然得到401。我想我已经尝试了所 查看详情
如何在 Asp.Net Core 3.0 WebAPI 中启用 CORS
】如何在Asp.NetCore3.0WebAPI中启用CORS【英文标题】:HowtoenableCORSinAsp.NetCore3.0WebAPI【发布时间】:2020-09-0721:49:39【问题描述】:我想通过Asp.NetCore3.0API项目启用CORS。这是生成的基本Asp.NetCoreApi模板。模板中的所有内容都是默认设置,... 查看详情
在 ASP.Net Core 5 WebAPI 中启用 CORS
】在ASP.NetCore5WebAPI中启用CORS【英文标题】:EnableCORSinASP.NetCore5WebAPI【发布时间】:2021-04-0906:31:40【问题描述】:有数以百万计的文章和问题与此问题相关,但我找不到我的代码有什么问题。我有Startup、StartupProduction和StartupDevelop... 查看详情
在 ASP.NET Core WebAPI 中获取 OData 计数
】在ASP.NETCoreWebAPI中获取OData计数【英文标题】:GettingODataCountinASP.NETCoreWebAPI【发布时间】:2020-03-0908:39:15【问题描述】:使用HassanHabib的SuperchargingASP.NETCoreAPIwithOData博客文章中的示例代码,我可以使用$count=true的OData查询获取记... 查看详情
获取 ASP .Net Core WebAPI 中的所有身份角色
】获取ASP.NetCoreWebAPI中的所有身份角色【英文标题】:GetallIdentityrolesinASP.NetCoreWebAPI【发布时间】:2021-10-1002:54:22【问题描述】:我的任务是获取数据库中的所有身份角色。我使用下面的代码来获取所有角色。在Asp.Net核心WebAPI中U... 查看详情
如何在 ASP.net Core WebAPI 中启用 CORS
】如何在ASP.netCoreWebAPI中启用CORS【英文标题】:HowtoenableCORSinASP.netCoreWebAPI【发布时间】:2021-12-3009:59:00【问题描述】:我要做什么我有一个托管在Azure免费计划上的后端ASP.NetCoreWebAPI(源代码:https://github.com/killerrin/Portfolio-Backend... 查看详情
如何在 Asp Net Core Web App(不是 WebAPI)中存储令牌
】如何在AspNetCoreWebApp(不是WebAPI)中存储令牌【英文标题】:HowtostoretokeninAspNetCoreWebApp(notWebAPI)【发布时间】:2020-08-0920:03:09【问题描述】:我想在Asp.NetCoreWebApp(不是WebAPI)中使用JWT令牌对用户进行身份验证。如何存储JWT令牌... 查看详情
在 ASP.NET Core WebApi 中处理多个租户
】在ASP.NETCoreWebApi中处理多个租户【英文标题】:HandlingmultipletenantsinASP.NETCoreWebApi【发布时间】:2022-01-0816:41:21【问题描述】:我开发了.NETCoreWebApi应用程序,并且有几个不同的客户使用具有不同配置的同一个应用程序。(应用... 查看详情
ASP.NET Core 2.2 WebAPI 405 方法不允许
】ASP.NETCore2.2WebAPI405方法不允许【英文标题】:ASP.NETCore2.2WebAPI405MethodNotAllowed【发布时间】:2019-09-2219:23:12【问题描述】:设置Windows10VisualStudio2017专业版ASP.NetCore2.2我要做什么针对我的WebAPI中使用PATCH动词的控制器方法运行集成... 查看详情
在 Asp.Net Core 5.0 中注册 HttpClient 时注入 ILogger
】在Asp.NetCore5.0中注册HttpClient时注入ILogger【英文标题】:InjectILoggerwhenregisteringHttpClientinAsp.NetCore5.0【发布时间】:2021-12-1721:14:06【问题描述】:在Asp.NetCore中注册自定义服务时,例如:services.AddScoped<ISomeService,SomeService>();然... 查看详情
检查用户是不是存在于 ASP.NET Core WebAPI JWT 身份验证中
】检查用户是不是存在于ASP.NETCoreWebAPIJWT身份验证中【英文标题】:CheckifuserexistsinASP.NETCoreWebAPIJWTAuthentication检查用户是否存在于ASP.NETCoreWebAPIJWT身份验证中【发布时间】:2020-08-0520:54:39【问题描述】:我已成功在我的WebAPI中设置... 查看详情
ASP.NET CORE 5.0 Identity 显示当前登录用户
】ASP.NETCORE5.0Identity显示当前登录用户【英文标题】:ASP.NETCORE5.0IdentityDisplaycurrentloggedinuser【发布时间】:2021-03-0309:26:36【问题描述】:我试图在IndexPage中显示哪个用户提交ticket。在我的模型中,我添加了属性publicint?UserIdget;set;pu... 查看详情
Asp.Net Core 5.0 中 EntityState.Detached 的空异常 [关闭]
】Asp.NetCore5.0中EntityState.Detached的空异常[关闭]【英文标题】:NullExceptiononEntityState.DetachedinAsp.NetCore5.0[closed]【发布时间】:2021-10-0106:22:20【问题描述】:我有一个用户个人资料页面,用户可以更新它自己的信息。当我尝试更新时... 查看详情
无法在 ASP.NET Core 5.0 下的 IIS 中托管 CoreWcf
】无法在ASP.NETCore5.0下的IIS中托管CoreWcf【英文标题】:CannothostCoreWcfinIISunderASP.NETCore5.0【发布时间】:2021-09-1606:02:15【问题描述】:我尝试将我的WCFWeb服务从.NetFramework4.7.1迁移到.Net5.0。我使用nuggetCoreWcf并尝试在IIS上运行它。阅... 查看详情
使用 JWT 令牌的 ASP.NET Core 网站到 WebApi 身份验证
】使用JWT令牌的ASP.NETCore网站到WebApi身份验证【英文标题】:ASP.NETCoreWebsitetoWebApiauthenticationusingJWTtoken【发布时间】:2019-07-1718:34:13【问题描述】:我正在开发一个ASP.NETCore2.2网站,用户需要登录然后使用它。我网站中的AccountContr... 查看详情
如何在 ASP.NET Core 5.0 中处理来自客户端的双重请求?
】如何在ASP.NETCore5.0中处理来自客户端的双重请求?【英文标题】:HowtohandledoublerequestsfromtheclientinASP.NETCore5.0?【发布时间】:2021-12-1309:13:22【问题描述】:客户端应用程序对服务器上的单个资源进行双重查询。第一帧没有授权头... 查看详情
如何按照存储库模式在 Asp.Net Core 5.0 项目上实现 .Net Core Identity?
】如何按照存储库模式在Asp.NetCore5.0项目上实现.NetCoreIdentity?【英文标题】:HowToImplement.NetCoreIdentityonAsp.NetCore5.0ProjectFollowingRepositoryPattern?【发布时间】:2021-09-0109:23:58【问题描述】:我正在研究.NetCore5.0技术,我目前的项目结... 查看详情
如何在无视图 WebAPI ASP.NET Core 应用程序中使用 [Authorize] 和防伪?
】如何在无视图WebAPIASP.NETCore应用程序中使用[Authorize]和防伪?【英文标题】:Howtouse[Authorize]andantiforgeryinaView-lessWebAPIASP.NETCoreapp?【发布时间】:2018-08-1100:34:33【问题描述】:当我无法保证客户端将使用什么平台时,我无法在严... 查看详情