Rya*_*mas 4 asp.net-web-api asp.net-core
我有一个 Web API 项目,其中有许多使用 API 密钥进行保护的端点。为了实现这一点,我编写了一些中间件来处理检查 API 密钥标头并验证它。该中间件在 Startup.cs 中配置
app.UseMiddleware<ApiKeyMiddleware>();
Run Code Online (Sandbox Code Playgroud)
这非常有效,但是我现在需要一个不需要任何授权的端点,以便可以在浏览器中查看它。我希望这可以通过使用AllowAnonymous属性来完成,但是中间件仍然检查 API 密钥。
我可以通过删除中间件并将 API 密钥检查到属性中来实现我想要的目的,但是有更好的方法吗?
编辑:
这是 API 密钥中间件实现。
public class ApiKeyMiddleware
{
private readonly RequestDelegate _next;
private const string API_KEY_HEADER = "z-api-key";
public ApiKeyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
if (!context.Request.Headers.TryGetValue(API_KEY_HEADER, out var extractedApiKey))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync($"Api Key was not found in request. Please pass key in {API_KEY_HEADEr} header.");
return;
}
var appSettings = context.RequestServices.GetRequiredService<IConfiguration>();
var validApiKey = appSettings.GetValue<string>(API_KEY_HEADER);
if (validApiKey != extractedApiKey)
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Invalid api key.");
return;
}
await _next(context);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 8
您可以使用HttpContext对象来访问端点和元数据(例如属性)。
var endpoint = context.GetEndpoint();
var isAllowAnonymous = endpoint?.Metadata.Any(x => x.GetType() == typeof(AllowAnonymousAttribute));
Run Code Online (Sandbox Code Playgroud)
然后在检查中添加条件以跳过。
if (isAllowAnonymous == true)
{
await _next(context);
return;
}
Run Code Online (Sandbox Code Playgroud)
注意:您应该将中间件放在Routing中间件之后才能使用GetEndpoint扩展方法。如果您的中间件位于Routing中间件
GetEndpoint扩展方法返回之前null
app.UseRouting();
app.UseMiddleware<ApiKeyMiddleware>();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2270 次 |
| 最近记录: |