MVC с Angular - ValidateAntiForgeryToken завершается ошибкой после перенаправления входа в Azure с Adal
У меня есть сайт MVC со встроенным угловым клиентом, и недавно я применил маркер 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 Bearer, а также проверкой защиты от подделки. Как ни странно, удаление проверки AzureAD в качестве теста не решило проблему.
Ошибка при сбое вызовов API отображается в выходных данных после входа в систему Adal как:
Предоставленный маркер защиты от подделки был предназначен для пользователя, основанного на утверждениях, отличного от текущего пользователя.
2 ответа
Насколько я понимаю, вы защищали контроллер с помощью токена. Для этой проблемы ожидается, что вы можете сослаться на ход проверки токенов анти-XSRF ниже (см. Эту ссылку):
Чтобы проверить входящие токены anti-XSRF, разработчик включает атрибут ValidateAntiForgeryToken в свое действие или контроллер MVC или вызывает @AntiForgery.Validate() со своей страницы Razor. Среда выполнения выполнит следующие шаги:
- Токен входящего сеанса и токен поля считываются, и токен анти-XSRF извлекается из каждого. Токены анти-XSRF должны быть идентичны на шаге (2) в процедуре генерации.
- Если текущий пользователь аутентифицирован, его имя сравнивается с именем пользователя, хранящимся в поле токена. Имена пользователей должны совпадать.
- Если настроен IAntiForgeryAdditionalDataProvider, среда выполнения вызывает свой метод ValidateAdditionalData. Метод должен возвращать логическое значение true.
Поскольку вы разрабатывали приложение SPA с внутренним веб-API, при запросе к веб-API оно всегда будет выдавать токен anti-XSRF без идентификатора. И когда вы отправляете запрос на сервер с токеном anti-XSRF и Azure AD, на этот раз веб-API уже аутентифицирует запрос с помощью токена Azure AD. И он всегда будет возвращать false при проверке токена anti-XSRF на соответствие идентификационной информации.
В этом сценарии, если серверная часть использует только аутентификацию медвежьего токена и сохраняет токен в хранилище сеанса, нет необходимости включать предотвращение XSRF, поскольку другие не могут украсть токен и подделать запрос.
Если ваш сервер также поддерживает проверку подлинности с помощью cookie-файлов или базовую аутентификацию, NTLM и т. Д., Вы можете отключить проверку идентичности, добавив в метод Application_Start следующее: AntiForgeryConfig.SuppressIdentityHeuristicChecks = true.(См. Эту ссылку)
Более подробно о XSRF/CSRF о oauth и веб-API вы можете сослаться на темы ниже:
Попробуйте заменить [ValidateAntiForgeryToken]
с [AutoValidateAntiforgeryToken]