将 API 视为连接 Web 应用不同部分的桥梁。
就像任何繁忙的桥梁一样,总是存在不速之客的风险。在我们的例子中,这些是喜欢利用任何弱点的黑客。
由于 C# .NET Core 广泛用于生成这些桥,因此保护它们非常重要。
现在我们知道了我们要面对的是什么,我们可以开始建立我们的防御。
让我们来谈谈一些关键但经常被忽视的事情 - 在 C# .NET Core API 中实现 HTTPS。
这有点像在你的前门上锁。当然,这是基本的,但它对于确保您的房屋安全至关重要。HTTPS 就是这样为您的数据做的。
简单来说,HTTPS 对在用户浏览器和 API 之间传输的数据进行加密。这就像发送一封只有发送者和接收者才能阅读的秘密信件。
现在让我们来了解实现的基础知识。
HSTS 是一种 Web 安全策略机制,有助于保护网站免受中间人攻击,例如协议降级攻击和 cookie 劫持。
代码示例:
builder.Services.AddHsts(options =>
{
options.Preload = true;
options.IncludeSubDomains = true;
options.MaxAge = TimeSpan.FromDays(60);
options.ExcludedHosts.Add("example.com");
options.ExcludedHosts.Add("www.example.com");
});
此代码片段使用预加载、包含子域和最大期限等选项配置 HSTS 策略。
将所有 HTTP 请求重定向到 HTTPS。这可确保客户端和服务器之间的通信是加密的。
代码示例:
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
此处,用于将所有 HTTP 请求重定向到 HTTPS。app.UseHttpsRedirection();
在 C# .NET Core API 项目中实现这些步骤将确保所有数据在传输过程中都经过加密,从而显著增强其安全性。
了解身份验证和授权之间的区别就像了解验证某人是谁和决定他们可以做什么之间的区别一样。让我们来分解一下。
这都是关于验证用户是谁。这就像在门口检查某人的身份证一样。在 ASP.NET Core 中,这由身份验证服务管理,涉及:
一旦我们知道用户是谁,授权就是确定他们可以访问的内容。这就像根据某人的 ID 级别决定建筑物中的哪些房间可以进入。
现在让我们看一些实际的代码示例。
这是在 中完成的,您可以在其中定义应用程序将使用的身份验证方案。Program.cs
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => builder.Configuration.Bind("JwtSettings", options))
.AddCookie(options => builder.Configuration.Bind("CookieSettings", options));
在此示例中,我们设置了 JWT 持有者和 cookie 身份验证方案。
中间件至关重要,因为它强制使用已注册的身份验证方案。
var app = builder.Build();
app.UseAuthentication();
此代码注册中间件以使用以前定义的身份验证方案。
您可以使用属性在控制器中或控制器内定义这些属性。Program.cs
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
});
在此示例中,“AdminOnly”策略仅允许具有“Admin”角色的用户访问某些资源。
使用控制器或操作上的属性来强制执行定义的策略或角色。[Authorize]
[Authorize(Policy = "AdminOnly")]
public IActionResult AdminDashboard()
{
// Controller action code here
}
此示例使用基于策略的授权来限制对 Admin Dashboard 的访问。
请记住,良好的安全实践是正确识别用户,然后仔细管理他们在应用程序中可以看到和执行的操作。
API 密钥管理就像拥有一个特殊的密码来控制谁可以访问您的 API。这对于安全和监视谁在使用你的服务都至关重要。
让我们看一个基本的实现示例。
首先为每个用户或服务创建唯一密钥。安全地存储这些密钥,最好是存储在数据库中,确保它们已加密。
使用自定义中间件验证每个请求的 API 密钥。中间件应将请求中提供的密钥与系统中存储的密钥进行比较。
public class ApiKeyMiddleware
{
private readonly RequestDelegate _next;
private readonly IConfiguration _configuration;
private const string ApiKeyHeaderName = "X-API-KEY";
public ApiKeyMiddleware(RequestDelegate next, IConfiguration configuration)
{
_next = next;
_configuration = configuration;
}
public async Task InvokeAsync(HttpContext context)
{
if (!context.Request.Headers.TryGetValue(ApiKeyHeaderName, out var extractedApiKey))
{
context.Response.StatusCode = 401; // Unauthorized
await context.Response.WriteAsync("API Key was not provided.");
return;
}
var authorizedKey = _configuration\["ApiKey"\];
if (authorizedKey != extractedApiKey)
{
context.Response.StatusCode = 403; // Forbidden
await context.Response.WriteAsync("Invalid API Key.");
return;
}
await _next(context);
}
}
在此代码片段中,中间件从请求标头中提取 API 密钥,并根据配置的密钥对其进行验证。
在 U 中注册此中间件,以确保为每个 API 调用执行它。Program.cs
app.UseMiddleware<ApiKeyMiddleware>();
输入验证和清理对于保护 API 免受可能危及安全性的恶意输入至关重要。
利用模型中的数据注释来强制执行验证规则。
public class Product
{
[Required]
[StringLength(100, MinimumLength = 3)]
public string Name { get; set; }
[Range(1, 1000)]
public decimal Price { get; set; }
}
此示例使用类似 、 和 的属性来定义产品实体的验证规则。[Required][StringLength][Range]
为标准批注不足的更复杂方案实现自定义验证逻辑。
public class MyCustomValidationAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// Custom validation logic
return ValidationResult.Success;
}
}
对于将在浏览器中呈现的输入(如 Web 应用程序中的用户生成内容),请确保进行清理以防止 XSS 攻击。使用专为清理 HTML 内容而设计的库来去除任何可能有害的脚本。
var sanitizedInput = HtmlSanitizer.Sanitize(input);
在 API 控制器中,在处理请求之前验证模型状态。
public IActionResult CreateProduct(Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// Proceed with processing
}
为了 API 安全,正确的输入验证和清理是不可协商的。
跨域资源共享 (CORS) 是一项安全功能,用于控制 API 响应跨域请求的方式。对于来自不同域的 Web 应用程序访问的 API 来说,这一点至关重要。
让我们看一下基本的实现:
在 或 中定义 CORS 策略:Program.csStartup.cs
builder.Services.AddCors(options =>
{
options.AddPolicy("MyAllowSpecificOrigins",
builder =>
{
builder.WithOrigins("https://example.com",
"https://www.contoso.com")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
在此示例中,将创建名为“MyAllowSpecificOrigins”的 CORS 策略,该策略允许来自指定源的任何标头和方法。
app.UseCors("MyAllowSpecificOrigins");
这将为您的应用程序启用 CORS 策略。
您还可以将 CORS 策略应用于控制器中的特定终结点:
[EnableCors("MyAllowSpecificOrigins")]
public class TestController : ControllerBase
{
// Controller actions
}
正确配置的 HTTP 标头可以增加额外的安全层。本部分将探讨如何在 C# .NET Core API 中实现安全标头。
通过指定允许加载的动态资源来防止 XSS 攻击。
app.Use(async (context, next) =>
{
context.Response.Headers.Add("Content-Security-Policy", "script-src 'self'");
await next();
});
防止 MIME 嗅探攻击。
app.Use(async (context, next) =>
{
context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
await next();
});
还有其他几个:
防止点击劫持。
强制执行与服务器的安全(HTTP over SSL/TLS)连接。
为防止滥用,请务必控制对 API 的请求速率。本部分将讨论如何实现速率限制和限制。
我不会在本文中讨论这个话题,而只是供参考。
保护 C# .NET Core API 需要多方面的方法。
我还建议查看有关此事的 youtube 视频,以了解当今可用的身份验证机制。
例如,JWT、OAuth 等。