Почему проверка AntiForgeryToken не проходит?

Я занимаюсь веб API приложение работает с использованием asp.net core2 а также Angular, Подробная конфигурация среды разработки находится здесь. Я пытаюсь настроить AntiForgeryToken проверка, но она продолжает терпеть неудачу. Я следил за конфигом. здесь, но мне пришлось изменить его, так как мое угловое приложение и серверы asp.net работают на двух разных портах, потому что запуск внешнего интерфейса не генерирует токен. Я запускаю бэкэнд, вызывая API дорожка (/api/Account/ContactInitialization) в компоненте приложения ngOnInit что позволило мне сгенерировать токен. Конфиг показан ниже,

IServiceCollection Обслуживание:

        services.AddAntiforgery(options =>
                {
                    options.HeaderName = "X-CSRF-TOKEN";
                    options.SuppressXFrameOptionsHeader = false;
                });

и в IApplicationBuilder Configure:

app.Use(next => context =>
                {
                    string path = context.Request.Path.Value;
                    if (

                        string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
                        string.Equals(path, "/api/Account/ContactInitialization", StringComparison.OrdinalIgnoreCase) ||
                        string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
                    {
                        // We can send the request token as a JavaScript-readable cookie, 
                        // and Angular will use it by default.
                         var tokens = antiforgery.GetAndStoreTokens(context);
                        context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
                            new CookieOptions() { HttpOnly = false });
                    }

                    return next(context);
                });

asp.net. генерирует два набора ключей,

введите описание изображения здесь

Я украсил свой метод [ValidateAntiForgeryToken] и я включил XSRF-TOKEN содержание куки в моем запросе заголовка. пока я продолжаю получать 400 (Bad Request) ответ после вызова API! что мне здесь не хватает?

Метод Контроллера,

    [Authorize]
    [ValidateAntiForgeryToken]
    [HttpPost]
    public IEnumerable<string> AutherizeCookie()
    {
        return new string[] { "Hello", "Auth Cookie" };
    }

мой подробный запрос заголовка выглядит ниже,

Запрос заголовка

3 ответа

Решение

Я предполагаю, что вы, вероятно, следовали документации, но затушевали соответствующие биты. То, что вы сделали, работает только для Angular, потому что Angular $http на самом деле добавит X-XSRF-TOKEN заголовок на основе XSRF-TOKEN печенье. (Обратите внимание, однако, что даже тогда вы установили свой заголовок как X-CSRF-TOKEN, который на самом деле не будет работать здесь. Это должно быть X-XSRF-TOKEN).

Однако, если вы не используете Angular, вы сами отвечаете за настройку заголовка в ваших AJAX-запросах, что вы, вероятно, игнорируете. В этом случае вам на самом деле не нужно изменять какую-либо конфигурацию токена защиты от подделки (имена заголовков, настройки файлов cookie и т. Д.). Вам просто нужно предоставить заголовок как RequestVerificationToken, Например, с помощью jQuery:

$.ajax({
    ...
    headers:
    {
        "RequestVerificationToken": '@GetAntiXsrfRequestToken()'
    },
    ...
});

Это будет работать для JavaScript в поле зрения. Если вам нужно сделать это во внешнем JS, вам нужно будет установить cookie, чтобы вместо этого вы могли получить значение из cookie. Помимо этого, применяется та же методология.

Если вы просто хотите изменить имя заголовка, вы можете сделать это; вам просто нужно изменить RequestVerificationHeader часть здесь к тому же значению.

Вам необходимо выполнить запрос XHR withCredentials=true, который заставит браузер установить cookie, в противном случае вы получите неверный запрос 400, потому что cookie отсутствует, а X-XSRF-TOKEN либо не установлен, либо установлен в пустую строку

Спасибо, @Chris_Pratt за указание на проблему с заголовком, которая у меня была. Однако, чтобы прояснить это, у меня были другие вопросы, которые будут рассмотрены ниже.

У меня был мой CORS неправильно настроен, мой рабочий код следующий,

services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy",
                    builder => builder
                        .WithOrigins("https://www.artngcore.com:4200") //Note:  The URL must be specified without a trailing slash (/).
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials());
            });

            services.AddAntiforgery(options =>
                {
                    options.HeaderName = "X-XSRF-TOKEN";
                    options.SuppressXFrameOptionsHeader = false;
                });  

и middleware конфигурация есть,

app.Use(next => context =>
               {
                   string path = context.Request.Path.Value;
                   var tokens = antiforgery.GetAndStoreTokens(context);
                   context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
                        new CookieOptions() { HttpOnly = false, 
Secure = true // set false if not using SSL });
                   return next(context);
               });

и в контроллере,

[Route("/api/[controller]/[action]")]
[EnableCors("CorsPolicy")]
public class AccountController : ArtCoreSecuredController ....

При чем тут хитрость в том, что токен должен обновляться после аутентификации. вызов API сразу после аутентификации (логина) сделает это. не забудьте добавить следующий заголовок к вашему запросу,

 const headers = new HttpHeaders({
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${this.cookieService.get('ArtCoreToken')}`,
            'X-XSRF-TOKEN': `${this.cookieService.get('XSRF-TOKEN')}`
        });

т.е.

    [HttpGet]
    [AllowAnonymous]
    public async Task<IActionResult> RefreshToken()
    {
        await Task.Delay(1);

        return StatusCode(200);

    } 

это то, что сработало для меня. Надеюсь, поможет.

Другие вопросы по тегам