ASP.NET Core API AntiforgeryToken 400 错误请求

问题描述 投票:0回答:1

为了调用应用了 AntiforgeryToken 的 API,我编写了一个像这样的 HttpClient。

[HttpPost]
public async Task<IActionResult> PhoneNumberAuth(int app_idx, string memberPhone)
{
....
....
HttpClient client = new HttpClient();

string url = "https://" + HttpContext.Request.Host.ToString() + Url.Action("PhoneNumberAuth", "Api")!;

AntiforgeryTokenSet requestTokenSet = _antiforgery.GetAndStoreTokens(HttpContext);
string requestTokenHeaderName = requestTokenSet.HeaderName!;
string requestToken = requestTokenSet.RequestToken!;

client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Add(requestTokenHeaderName, requestToken);

var authenticationNumber = new
{
    receiveNumber = memberPhone,
    senderNumber = smsInfo.sms_phoneNumber
};

string dataJson = Newtonsoft.Json.JsonConvert.SerializeObject(authenticationNumber);
StringContent content = new StringContent(dataJson, Encoding.UTF8, "application/json");

HttpResponseMessage response = await client.PostAsync(url, content);

return Ok();

}

但是,这将导致 400 Bad Request 错误。

如果我将 [IgnoreAntiforgeryToken] 属性应用于 API,我将得到 200 OK 而不是错误。

[IgnoreAntiforgeryToken]
[HttpPost("[Action]")]
public async Task<IActionResult> PhoneNumberAuth()
{
...
    return Ok();
}

请注意,两个 PhoneNumberAuth 方法存在于不同的控制器中。

为什么会出现错误?

在视图中,我通过 Javascript 调用 PhoneNumberAuth(int app_idx, string memberPhone) 方法,该方法又调用 PhoneNumberAuth API。

我不直接调用PhoneNumberAuth API,因为我们需要处理敏感信息。

我无法应用 [IgnoreAntiforgeryToken] 属性,也无法创建这样的操作方法。


代币会出错吗?

View 是这样处理的

@{
    var requestToken = Antiforgery.GetAndStoreTokens(Context);
}
...
$.ajax({
    url: '@Url.Action("PhoneNumberAuth", "Api")',
    headers:
    {
        '@requestToken.HeaderName': '@requestToken.RequestToken'
    },
    type: 'post',
    success: function(result) {
                            
    },
    error: function(ajaxContext) {
                            
    }
});

为了在控制器的操作方法中调用它(PhoneNumberAuth(int app_idx,string memberPhone)),我在cs中编写了以下内容。

private readonly IAntiforgery _antiforgery;

public SiteController(IAntiforgery antiforgery)
{
    _antiforgery = antiforgery;
}
...
AntiforgeryTokenSet requestTokenSet = _antiforgery.GetAndStoreTokens(HttpContext);

我在这段代码中遗漏了什么吗?

asp.net-core httpclient antiforgerytoken
1个回答
0
投票

请注意,无需应用防伪造令牌保护来防止 ASP.NET CORE Web API 中的 CSRF 攻击。

如果您想保护您的API,您可以尝试将此类基于Token等的身份验证和授权机制集成到您的API项目中。

如果您确实想使用API端点实现AntiforgeryToken验证,您可以参考以下示例代码。

// Add Antiforgery services
builder.Services.AddAntiforgery(options =>
{
    options.HeaderName = "X-XSRF-TOKEN";
});

builder.Services.AddControllersWithViews(options =>
{
    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});

//...

控制器和动作

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    private readonly IAntiforgery _antiforgery;

    public ValuesController(IAntiforgery antiforgery)
    {
        _antiforgery = antiforgery;
    }

    [HttpGet("GetToken")]
    public IActionResult GetToken()
    {
        var tokens = _antiforgery.GetAndStoreTokens(HttpContext);
        return Ok(new { token = tokens.RequestToken });
    }

    [ValidateAntiForgeryToken]
    [HttpPost("[Action]")]
    public async Task<IActionResult> PhoneNumberAuth()
    {
        //...
        return Ok("success");
    }

    //...

示例和测试请求

###
# get token
GET  https://localhost:7014/api/values/GetToken HTTP/1.1

###
# make request with XSRF token
POST https://localhost:7014/api/values/PhoneNumberAuth HTTP/1.1
X-XSRF-TOKEN: CfDJ8KmhRjRu7cpNjZEYjJecX1dG8RozjhyUrthrU0kNYV-9auYN47VfKORxLOo_9G78ElX14Wcx2kQmXn9tJiRSIj6REVu0c2Z1iENmm7BaBwmxxGyB_hB2L2olrRKSY3ZeZS8Bl44eU6OS0zkho4FZKAE

测试结果

test result

© www.soinside.com 2019 - 2024. All rights reserved.