如果我告诉您,保护 API 比您想象的要简单,会怎么样?如果您认为向 .NET 8 应用程序添加强大的安全性需要大量复杂的设置,那么想象一下只需几行代码即可实现 API 密钥身份验证的轻松程度。突然之间,您的服务变得安全并受到保护,不会受到未经授权的访问!您知道在 ASP.NET Core 中实施 API 密钥身份验证是多么容易吗?如果您有兴趣让您的 API 免受窥探,那么您绝对应该继续阅读。
API 安全背后的故事
在当今的互联世界中,API 无处不在,为从移动应用程序到云服务的一切提供支持。随着 API 使用量的增加,保护这些端点不再是一种选择,而是一种必需品。弱身份验证或不存在身份验证可能会暴露敏感数据并危及您的系统。保护 API 的一种简单而有效的方法是使用 API 密钥身份验证。
API 密钥是一种简单的身份验证形式,它允许客户端通过在请求中包含密钥来访问 API。它不如 OAuth 或 JWT 全面,但对于需要基本访问控制而又不复杂的场景,它是一个很好的解决方案。
让我们探讨如何使用 .NET 8 在 ASP.NET Core 应用程序中实现 API 密钥身份验证。我们将逐步介绍整个过程,最后,您将清楚地了解如何有效地保护您的 API。
第 1 步:设置 ASP.NET Core 项目
首先,让我们创建一个新的 ASP.NET Core Web API 项目。
dotnet new webapi -n ApiKeyAuthExample
在您喜欢的 IDE 中打开新创建的项目,并添加一个名为 :WeatherForecastController
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
此控制器提供用于获取天气预报的基本终端节点。现在,让我们添加身份验证以使用 API 密钥保护此终端节点。
第 2 步:添加 API 密钥身份验证中间件
要添加 API 密钥身份验证,我们需要创建自定义中间件,它将:
检查每个传入请求是否存在 API 密钥。
验证 API 密钥。
如果 API 密钥缺失或无效,则拒绝请求。
创建 Middleware
创建一个名为 的新文件夹,并添加一个名为 的类 :MiddlewareApiKeyMiddleware
public class ApiKeyMiddleware
{
private readonly RequestDelegate _next;
private const string ApiKeyHeaderName = "X-API-KEY";
public ApiKeyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
if (!context.Request.Headers.TryGetValue(ApiKeyHeaderName, out var extractedApiKey))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("API Key was not provided.");
return;
}
var appSettings = context.RequestServices.GetRequiredService<IConfiguration>();
var apiKey = appSettings.GetValue<string>("ApiKey");
if (!apiKey.Equals(extractedApiKey))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Unauthorized client.");
return;
}
await _next(context);
}
}
此中间件检查请求标头 () 中的 API 密钥,并将其与配置中存储的值进行比较。如果密钥缺失或无效,则返回状态。X-API-KEY401 Unauthorized
第 3 步:注册 Middleware
在 中,将中间件添加到请求管道的行之前:Program.csapp.MapControllers()
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseMiddleware<ApiKeyMiddleware>();
app.MapControllers();
app.Run();
第 4 步:存储和管理 API 密钥
您需要一种方法来安全地存储 API 密钥。为简单起见,我们将在此示例中使用 App settings。在文件中,为 API 密钥添加一个条目:appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ApiKey": "my-super-secret-api-key"
}
在实际应用程序中,您可以将 API 密钥存储在更安全的位置,例如 Azure Key Vault、AWS Secrets Manager 或环境变量。
第 5 步:测试 API 密钥身份验证
尝试在没有 API 密钥的情况下调用终端节点:WeatherForecast
curl -X GET "https://localhost:5001/WeatherForecast"
您应该会收到一条消息“未提供 API 密钥”的响应。401 Unauthorized
现在,再次尝试该请求,但这次包括 API 密钥:
curl -X GET "https://localhost:5001/WeatherForecast" -H "X-API-KEY: my-super-secret-api-key"
您应该会得到一个包含天气预报数据的成功响应。
第 6 步:增加复杂性 — 基于角色的 API 密钥授权
假设您的应用程序需要对各种 API 密钥具有不同级别的访问权限。您可以扩展中间件以支持基于 API 密钥的基于角色的授权。
更新 Middleware
为 API 密钥添加角色检查:
public class ApiKeyMiddleware
{
private readonly RequestDelegate _next;
private const string ApiKeyHeaderName = "X-API-KEY";
public ApiKeyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
if (!context.Request.Headers.TryGetValue(ApiKeyHeaderName, out var extractedApiKey))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("API Key was not provided.");
return;
}
var configuration = context.RequestServices.GetRequiredService<IConfiguration>();
var apiKeys = configuration.GetSection("ApiKeys").Get<Dictionary<string, string>>();
if (!apiKeys.TryGetValue(extractedApiKey, out var role))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Unauthorized client.");
return;
}
// Store the role for further processing
context.Items["UserRole"] = role;
await _next(context);
}
}
在appsettings.json
{
"ApiKeys": {
"my-admin-api-key": "Admin",
"my-user-api-key": "User"
}
}
在 Controller 中使用 User 角色
[ApiController]
[Route("[controller]")]
public class SecureController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
var userRole = HttpContext.Items["UserRole"] as string;
if (userRole == "Admin")
{
return Ok("Welcome, Admin!");
}
return Forbid("You do not have permission to access this resource.");
}
}
只需几个步骤,我们就为 ASP.NET Core 应用程序添加了强大的 API 密钥身份验证。我们还对其进行了扩展以支持基于角色的授权,从而增加了对访问的更多控制。API 密钥身份验证是保护 API 以简化用例的好方法,使用 .NET 8,实现此模式比以往任何时候都更容易。
如果你喜欢我的文章,请给我一个赞!谢谢