MVC с Angular — сбой ValidateAntiForgeryToken после перенаправления входа в Azure с помощью Adal

У меня есть сайт MVC со встроенным клиентом angular, и я недавно реализовал токен XSRF для защиты от подделки в качестве меры безопасности.

Я настроил его в Startup.cs следующим образом:

services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");

app.Use(next => context =>
        {
            if (string.Equals(context.Request.Path.Value, "/", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(context.Request.Path.Value, "/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);
        });

И я реализовал это в своем угловом интерфейсе следующим образом:

{ provide: XSRFStrategy, useFactory: xsrfFactory}

export function xsrfFactory(): CookieXSRFStrategy {
return new CookieXSRFStrategy('XSRF-TOKEN', 'X-XSRF-TOKEN');
}

И защита моих контроллеров, таких как:

[Authorize] //Validation of AzureAD Bearer Token.
[ValidateAntiForgeryToken]
public class UserController : Controller

Предполагается, что заголовок X-XSRF-TOKEN будет проверяться при любом вызове моего API, и это успешно работает для всех вызовов в исходном сеансе. Однако мое приложение использует Adal для входа пользователя в систему, и после перенаправления после успешного входа этот этап проверки завершается неудачно, и я получаю 400 от своего API для любых последующих вызовов.

Исходный заголовок X-XSRF-TOKEN по-прежнему отправляется со всеми исходящими запросами от моего углового клиента после входа в систему, поэтому я подозреваю, что на стороне моего сервера больше нет токена для проверки, или мой сервер сгенерировал новый, а мой клиент не т получить его. Но по какой-то причине он ломается, и его очень сложно отлаживать без создания какого-то пользовательского фильтра, поэтому я могу видеть, что происходит внутри него.

Есть ли способ сбросить этот токен после перенаправления на стороне клиента, чтобы и мой сервер, и клиент снова делились общими знаниями о нем? Или я должен генерировать токен, например, в моем Index.html?

ИЗМЕНИТЬ

Отредактировано украшение контроллера выше для отсутствующего атрибута [Authorize].

Таким образом, мой контроллер защищен этапом проверки токена носителя AzureAD, а также проверки защиты от подделки. Как ни странно, удаление проверки AzureAD в качестве теста не решило проблему.

Ошибка при неудачных вызовах API отображается в выводе после входа в Adal как:

Предоставленный маркер защиты от подделки предназначался для другого пользователя на основе утверждений, отличного от текущего пользователя.


person JonnyKnottsvill    schedule 04.07.2017    source источник
comment
Когда вы аутентифицируете адал, вы использовали всплывающую страницу? Если да, полезно ли установить для popUp значение false?   -  person Fei Xue - MSFT    schedule 05.07.2017
comment
@ FeiXue-MSFT Нет, это не всплывающее окно, я перехожу к login.microsoft.com/xxx и предоставляю redirectUrl для успешного входа в систему. Пожалуйста, смотрите мое редактирование для ошибки, обнаруженной в выводе, когда вызовы API терпят неудачу. Я также добавил, что сначала проверяю токен носителя пользователя с помощью конвейера авторизации AzureAD. Я пропустил это ранее.   -  person JonnyKnottsvill    schedule 05.07.2017


Ответы (2)


Насколько я понимаю, вы защищали контроллер с помощью токена. Поскольку эта проблема ожидается, вы можете просмотреть ход проверки маркеров защиты от XSRF ниже (см. эта ссылка):

Чтобы проверить входящие токены анти-XSRF, разработчик включает атрибут ValidateAntiForgeryToken в свое действие или контроллер MVC или вызывает @AntiForgery.Validate() со своей страницы Razor. Среда выполнения выполнит следующие шаги:

  1. Токен входящего сеанса и токен поля считываются, и из каждого из них извлекается токен анти-XSRF. Токены анти-XSRF должны быть идентичными на шаге (2) процедуры создания.
  2. Если текущий пользователь аутентифицирован, его имя пользователя сравнивается с именем пользователя, хранящимся в токене поля. Имена пользователей должны совпадать.
  3. Если настроен IAantiForgeryAdditionalDataProvider, среда выполнения вызывает его метод ValidateAdditionalData. Метод должен возвращать логическое значение true.

Поскольку вы разрабатывали приложение SPA с внутренним веб-API, при запросе к веб-API он всегда будет выдавать токен анти-XSRF без идентификации. И когда вы отправляете запрос на серверную часть с анти-XSRF и токеном Azure AD, на этот раз веб-API уже выполняет аутентификацию запроса через токен Azure AD. И он всегда будет возвращать false при проверке токена анти-XSRF на соответствие идентификационной информации.

В этом сценарии, если серверная часть использует только аутентификацию медвежьего токена и хранит токен в хранилище сеансов, нет необходимости включать предотвращение XSRF, поскольку другие не могут украсть токен и подделать запрос.

Если ваш сервер также поддерживает аутентификацию cookie или базовую аутентификацию, NTLM и т. д., вы можете отключить проверку личности, добавив в свой метод Application_Start следующее: AntiForgeryConfig.SuppressIdentityHeuristicChecks = true (см. эта ссылка)

Более подробную информацию о XSRF/CSRF, oauth и веб-API вы можете найти в следующих темах:

Как ValidateAntiForgeryToken подходит для Интернета API, к которым можно получить доступ через веб-сайт или собственное приложение?

AntiForgeryToken плохо работает с OAuth через WebAPI

person Fei Xue - MSFT    schedule 06.07.2017

Попробуйте заменить [ValidateAntiForgeryToken] на [AutoValidateAntiforgeryToken]

https://github.com/aspnet/Antiforgery/blob/dev/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgeryTokenGenerator.cs

person MattM2017    schedule 04.11.2017