繁体   English   中英

在外部消费者(应用程序)中使用 ASP.NET Core 6 Web API Antiforgery Token,无需身份验证

[英]Using ASP.NET Core 6 Web API Antiforgery Token in extern consumer (App) without Authentication

How can i use an Antiforgery Token in ASP.NET Core 6 Web API with an extern consumer like a iOS or Android App? 我不需要对请求进行用户身份验证。 该应用程序托管在另一个域上。

我已经开发了一个带有防伪令牌的Web API 和 ASP.NET 6 ZE4005C19182272 一切正常。 但是我如何开发一个使用这个 Web API 的外部应用程序? 问题,我不知道如何从“外部”应用程序创建防伪令牌? 如何配置应用程序以使用 Web API 和防伪令牌?

在构建 API 时,无需针对 CSRF 攻击实施 Anti-Forgery Token 保护,大多数 API 都是从外部客户端调用的,并且 API 保护使用不同的方法实现:

  • 使用 API 密钥。
  • 使用基本身份验证。
  • 使用 OpenID 连接。

因为我们想要的是防止恶意客户端调用我们的 API。

但是,如果您从您的网站使用 Ajax 调用 API,则可以集成防伪令牌保护,您可以在 StackOverflow 上查看此答案以获取有关如何实现它的更多详细信息。

但由于您要使用上述方法之一从外部应用程序调用 API,只需 go。

有关 CSRF 攻击以及如何实施防伪令牌保护的更多详细信息,请查看Microsoft 文档上的这篇文章。

另外,请查看 RedHat 的这篇文章以获取有关API 安全性的更多信息。

我不同意“在构建 API 时没有必要针对 CSRF 攻击实施防伪令牌保护”的答案。

仍然存在入侵者以某种方式强制客户端应用发送恶意请求的风险。


To configure Anti-Forgery Protection in .NET Web API (without using MVC Views), you need to use the package Microsoft.AspNetCore.Antiforgery .

请记住,有两个正在验证的令牌:Cookie 令牌和请求令牌(来自 HTTP 标头)。

 // Field IAntiforgery _antiforgery; var tokens = _antiforgery.GetAndStoreTokens(HttpContext);

因此, tokens将包含以下值:

 { "CookieToken": "CfDJ8JPuS3COPd9AmHCMBz_IFVdVzR8cfeD2or9v3qMLlWgRiN812hKbkh4o8TpYl4AdA3uJ3FeoY3eozx59q_uSnloXl80nLEd6twLzkDdn4AifcsGWcwaAxWSrGTui0vwl7-SHjftCfkbj9pAlDC_DS0Q", // Ignore this: built-in mechanism for forms "FormFieldName": "__RequestVerificationToken", "HeaderName": "X-XSRF-TOKEN", "RequestToken": "CfDJ8JPuS3COPd9AmHCMBz_IFVfnP50wBywG2WJmFoYA7nx-VGzBjPRY16-p3BBFRMUGHt4cz-M-VrZ_jX_7vUoIt0OX3xhHNw8swt0CebGa4P41cVej2F_DvvayOvrhbY6s3Z2U1aZWHmAvBT8NlH7ueRE" }

注意CookieTokenRequestToken是不同的。

Cookie 令牌是自动处理的。 但是Request Token应该由我们处理。

  1. 创建验证中间件:

     public class AntiforgeryMiddleware: IMiddleware { private readonly IAntiforgery _antiforgery; public AntiforgeryMiddleware(IAntiforgery antiforgery) { _antiforgery = antiforgery; } public async Task InvokeAsync(HttpContext context, RequestDelegate next) { var isGetRequest = string.Equals("GET", context.Request.Method, StringComparison.OrdinalIgnoreCase); if (.isGetRequest) { _antiforgery.ValidateRequestAsync(context).GetAwaiter();GetResult(); } await next(context); } }
  2. 在您的 Web API 应用程序中配置 DI:

     // Startup.cs public void ConfigureServices(IServiceCollection services) { //... // Extension method comes from the `Microsoft.AspNetCore.Antiforgery` package services.AddAntiforgery(options => { options.HeaderName = "X-XSRF-TOKEN"; }); services.AddScoped<AntiforgeryMiddleware>(); }
  3. 配置验证中间件:

     // Startup.cs public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { //... app.UseMiddleware<AntiforgeryMiddleware>(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
  4. 创建 XSRF 令牌端点:

     [Route("api/xsrf-token")] [ApiController] public class AntiForgeryController: Controller { private IAntiforgery _antiforgery; public AntiForgeryController(IAntiforgery antiforgery) { _antiforgery = antiforgery; } [IgnoreAntiforgeryToken] public IActionResult Get() { // Creates and sets the cookie token in a cookie // Cookie name will be like ".AspNetCore.Antiforgery.pG4SaGh5yDI" var tokens = _antiforgery.GetAndStoreTokens(HttpContext); // Take request token (which is different from a cookie token) var headerToken = tokens.RequestToken; // Set another cookie for a request token Response.Cookies.Append("XSRF-TOKEN", headerToken, new CookieOptions { HttpOnly = false }); return NoContent(); } }
  5. 在客户端上向 URL /api/xsrf-token发出请求。

    然后读取请求令牌 cookie XSRF-TOKEN并将其设置为X-XSRF-TOKEN HTTP header 用于非 GET 请求:

     X-XSRF-TOKEN: <request-token>

前段时间我是安全冠军,所以知道什么是安全(但最近没有关注这个话题)。 但是在每次会议或培训中,通常有两件事是正确的:

  1. 安全很难做到正确...
  2. 安全性很难做到正确......所以永远不要自己做!

在您的情况下,问题在于 API 中没有防伪令牌(CSRF 保护)。 它仅在 MVC 中可用,并且有充分的理由:

  • MVC 使用 session 并在服务器上呈现表单,因此在服务器端生成令牌,发送到 HTML 表单并存储在用户 session 中以进行 POST 验证。
  • 大多数 MVC 站点都使用受 CSRF post 攻击影响的基于 Cookie 的身份验证
  • REST API 应该是无状态的,这意味着默认没有 session。 响应不是 HTML 而是 XML/JSON 数据。 “Form” POST 发生在其他系统中,并且以安全的方式公开 Antiforgery 令牌。
  • 大多数 RestFul API 都在使用 oAuth2 或一些不受 CSRF 影响的 Bearer token Auth !!!

所以答案是你的问题的另一个问题。 您是否在 API 中使用基于 Cookie 的授权?

如果不是,那么您不应该使用 Antiforgery 令牌,它不会影响您的 API ...否则您应该切换到 Bearer Auth 标头并设置好。

也请忽略编码答案,因为它们有很多问题。 实现将编译,代码运行肯定但充满安全问题(自制安全)。 例如,存储在 Cookie 中的 Token 是 CSRF 攻击的基础 Cookies 由浏览器自动附加到请求中,GET 方法是安全的,甚至无法防御,等等......

Homebrew 安全性可能会产生错误的信心(是的,我锁定了它):

自制安全失败...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM