В результате я не отправил случайный токен, который был создан клиентской стороной с каждым запросом. Я не мог заставить его работать.
Так вот как я решил мою проблему (вид):
(1) По каждому запросу (включая первый), я отправить обратно из моего API куки в заголовках ответа с именем «XSRF -TOKEN "и рандомизированное значение, связанное с ним. Это имя, которое AngularJS ищет по умолчанию при использовании своей защиты CSRF.
(2) Что происходит в запросе после получения этого токена, является то, что AngularJS использует значение этого токена при отправке файла cookie в заголовки запроса под названием «XSRF-TOKEN», а также заголовок «X-XSRF-TOKEN», с этим значением токена.
Так что мой API обрабатывает рандомизацию токена XSRF, и мое приложение по-прежнему не имеет гражданства. Я использую Web API и использую глобальный фильтр для обработки этого маркера XSRF. Ниже приведен мой код (на C#) для этого. Я больше не имею какой-либо код обработку этого в интерфейсе (как это не кажется это будет необходимо):
public class ValidateAntiForgeryToken : ActionFilterAttribute
{
private const string XsrfCookieName = "XSRF-TOKEN";
private const string XsrfHeaderName = "X-XSRF-TOKEN";
private const string CsrfTokenSalt = "RANDOM SALT";
public override void OnActionExecuting(HttpActionContext filterContext)
{
string requestMethod = filterContext.Request.Method.Method;
Boolean isValid = true;
if (requestMethod != "GET")
{
var headerToken = filterContext.Request.Headers.Where(x => x.Key.Equals(XsrfHeaderName, StringComparison.OrdinalIgnoreCase))
.Select(x => x.Value).SelectMany(x => x).FirstOrDefault();
var cookieToken = filterContext.Request.Headers.GetCookies().Select(x => x[XsrfCookieName]).FirstOrDefault();
// check for missing cookie or header
if (cookieToken == null || headerToken == null)
{
isValid = false;
}
// ensure that the cookie matches the header
if (isValid && !String.Equals(headerToken, cookieToken.Value, StringComparison.OrdinalIgnoreCase))
{
isValid = false;
}
if (!isValid)
{
filterContext.Response = filterContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
filterContext.Response.ReasonPhrase = "Unauthorized to make that request.";
return;
}
}
base.OnActionExecuting(filterContext);
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
string textToHash = RandomStringGeneration();
string cookieText = HashService.HashText(textToHash, CsrfTokenSalt);
var cookie = new CookieHeaderValue(XsrfCookieName, HttpUtility.UrlEncode(cookieText));
/* don't use this flag if you're not using HTTPS */
cookie.Secure = true;
cookie.HttpOnly = false; // javascript needs to be able to get this in order to pass it back in the headers in the next request
/* if you have different environments on the same domain (which I did in one application using this code) make sure you set the path to be ApplicationPath of the request. Case sensitivity does matter in Chrome and IE, so be wary of that. */
cookie.Path = "/";
actionExecutedContext.Response.Headers.AddCookies(new[] { cookie });
base.OnActionExecuted(actionExecutedContext);
}
}
Вот мой HashService.HashText (код):
public class HashService
{
public static string HashText(string text, string salt)
{
SHA512Managed hashString = new SHA512Managed();
byte[] textWithSaltBytes = Encoding.UTF8.GetBytes(string.Concat(text, salt));
byte[] hashedBytes = hashString.ComputeHash(textWithSaltBytes);
hashString.Clear();
return Convert.ToBase64String(hashedBytes);
}
}
Надеется, что это помогает кто-то в будущем в приложениях без гражданства. К сожалению, токен, отправленный обратно, сравнивается только с самим собой в значении cookie и значении заголовка. Это единственный способ проверить это прямо сейчас (что я считаю довольно безопасным).Я могу создать целую новую таблицу для защиты XSRF и использовать ее для проверки того, что токен действительно тот, который должен использовать пользователь. Это единственный способ, с помощью которого я могу сосредоточиться, сохраняя свой API без гражданства.
Я наткнулся на это решение после прочтения HTTP документации $ для AngularJS, который диктует:
Запрос Cross Site Подделка (XSRF) Защита: XSRF является метод, с помощью который неавторизованный сайт может получить личные данные пользователя. Угловой обеспечивает механизм противодействия XSRF. При выполнении запросов XHR служба $ http считывает токен из файла cookie (по умолчанию XSRF-TOKEN) и устанавливает его как HTTP-заголовок (X-XSRF-TOKEN). Поскольку только JavaScript , который работает в вашем домене, может читать файл cookie, ваш сервер может быть заверил, что XHR получен из JavaScript, запущенного в вашем домене. Заголовок не будет установлен для междоменных запросов.
Чтобы воспользоваться этим, вашему серверу необходимо установить токен в файле cookie , который можно прочитать в JavaScript, который называется XSRF-TOKEN, в первом запросе GET HTTP . При последующих запросах XHR сервер может проверить, что файл cookie соответствует HTTP-заголовку X-XSRF-TOKEN, и поэтому убедитесь, что только JavaScript, работающий в вашем домене, мог отправить запрос. Маркер должен быть уникальным для каждого пользователя и должен быть проверен сервером (чтобы JavaScript не мог составлять свои жетоны). Мы, , рекомендуем, чтобы токен являлся дайджестом аутентификации вашего сайта. cookie с солью для дополнительной безопасности.
Название заголовков может быть задана с помощью xsrfHeaderName и xsrfCookieName свойства либо $ httpProvider.defaults на конфигурации времени, $ http.defaults во время выполнения, или каждого запроса конфигурации объект.
> Учитывая, что веб-сайт разрешен только для чтения/записи Cookie для собственного домена, только реальный сайт может отправлять одно и то же значение в обоих заголовках. Что происходит, когда несколько веб-сайтов используют один и тот же домен? Разве это не позволяет вашему сайту подвергнуться нападению со стороны одного из других? Я полагаю, что если вы точно знаете, что ваш сайт будет единственным в домене, этот подход может работать. –