.NET Core Web API 密钥
Posted
技术标签:
【中文标题】.NET Core Web API 密钥【英文标题】:.NET Core Web API key 【发布时间】:2018-01-29 14:24:25 【问题描述】:我正在开发一个应用程序,用户可以通过用户名和密码进行身份验证,我们提供了一个 JWT 令牌,然后在服务器上进行验证。
我想补充的一件事是能够拥有一个特殊的 API 密钥 (guid),用户可以在与此应用程序集成时使用它,而不是使用用户名和密码。
我不确定如何执行此操作,因为身份验证部分似乎有点像黑匣子(使用 Aspnet Identity)。
这是我的一些身份验证设置代码。
Startup.cs
public void ConfigureServices(IServiceCollection services)
// Add framework services.
services.AddDbContext<OmbiContext>(options =>
options.UseSqlite("Data Source=Ombi.db"));
services.AddIdentity<OmbiUser, IdentityRole>()
.AddEntityFrameworkStores<OmbiContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options =>
options.Password.RequireDigit = false;
options.Password.RequiredLength = 1;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
);
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IMemoryCache cache)
var tokenOptions = (IOptions<TokenAuthentication>)app.ApplicationServices.GetService(
typeof(IOptions<TokenAuthentication>));
var ctx = (IOmbiContext)app.ApplicationServices.GetService(typeof(IOmbiContext));
var tokenValidationParameters = new TokenValidationParameters
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOptions.Value.SecretKey)),
RequireExpirationTime = true,
ValidateLifetime = true,
ValidAudience = "Ombi",
ValidIssuer = "Ombi",
ClockSkew = TimeSpan.Zero
;
app.UseJwtBearerAuthentication(new JwtBearerOptions()
Audience = "Ombi",
AutomaticAuthenticate = true,
TokenValidationParameters = tokenValidationParameters,
);
//....
上述代码在控制器上具有[Authorized]
属性并检查角色等时有效。
任何人都知道如何在包含此特殊 API 密钥的所有请求上传递某种 Api-Key
标头以传递 [Authorized]
属性? (密钥存储在数据库中。)
【问题讨论】:
***.com/questions/31464359/… @stuartd 不确定上述是否适用,查看它我需要为每个控制器定义该策略,在这种情况下,API Key 标头将始终需要存在。基本上我正在寻找一种方法来向授权我的服务器提供秘密。 您在请求中提供带有授权标头的不记名令牌。并且根据授权服务器所在的位置,您需要对其进行验证。 IE。在 azure AD 中,如果您只想针对服务器中的硬编码密钥进行验证,您可以在 appregistration 下添加一个 api,您可以通过自己的声明验证器进行验证,检查 AuthorizationHandler 类 【参考方案1】:这就是我最后所做的:
public static void ApiKeyMiddlewear(this IApplicationBuilder app, IServiceProvider serviceProvider)
app.Use(async (context, next) =>
if (context.Request.Path.StartsWithSegments(new PathString("/api")))
// Let's check if this is an API Call
if (context.Request.Headers["ApiKey"].Any())
// validate the supplied API key
// Validate it
var headerKey = context.Request.Headers["ApiKey"].FirstOrDefault();
await ValidateApiKey(serviceProvider, context, next, headerKey);
else if (context.Request.Query.ContainsKey("apikey"))
if (context.Request.Query.TryGetValue("apikey", out var queryKey))
await ValidateApiKey(serviceProvider, context, next, queryKey);
else
await next();
else
await next();
);
private static async Task ValidateApiKey(IServiceProvider serviceProvider, HttpContext context, Func<Task> next, string key)
// validate it here
var valid = false;
if (!valid)
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
await context.Response.WriteAsync("Invalid API Key");
else
var identity = new GenericIdentity("API");
var principal = new GenericPrincipal(identity, new[] "Admin", "ApiUser" );
context.User = principal;
await next();
自从我回答了原始问题(答案仍然有效)以来,情况发生了很大变化。但你可以在这里阅读:https://tidusjar.github.io/2019/03/25/net-core-jwt-api-key/
【讨论】:
您能否详细说明您想在 ValidateApiKey 的 else 主体上实现什么?我担心的是验证 ApiKey,但随后在具有属性 [Authorize] 的操作上被拒绝。您如何处理中间件以跳过该属性? 基本上await context.Response.WriteAsync("Invalid API Key");
然后`await next.Invoke(context);`。你可以在这里看到这个:github.com/tidusjar/Ombi/blob/master/src/Ombi/…
嘿@JamieRees 感谢这个解决方案,它帮助了我很多!您如何看待检查 ApiKey,我们查找 client_id 并检查 client_id 是否有权访问受保护的范围(如 Api 资源)?【参考方案2】:
在此链接上有一篇关于在标头请求中使用 api 键的好文章: http://www.mithunvp.com/write-custom-asp-net-core-middleware-web-api/
总而言之,在 ASP.NET Core 中,您可以使用中间件来控制 http 管道配置。中间件有效地替代了早期版本的 asp.net MVC 中使用的 HttpHandlers。
【讨论】:
以上是关于.NET Core Web API 密钥的主要内容,如果未能解决你的问题,请参考以下文章
.Net Core 自定义身份验证使用 API 密钥和 Identity Server 4
.Net Core JWT 身份验证与自定义 API 密钥中间件
根据 ASP.NET Core 请求标头中提供的 API 密钥授权用户
如何在 ASP .NET Core Web 应用程序中向 apsettings.js 添加“密钥”及其“名称”