Что такое XsrfKey и я должен установить XsrfId на что-то другое?
в моем веб-приложении MVC 5 у меня есть это (в AccountController.cs):
// Used for XSRF protection when adding external sign ins
private const string XsrfKey = "XsrfId";
и
public string SocialAccountProvider { get; set; }
public string RedirectUri { get; set; }
public string UserId { get; set; }
public override void ExecuteResult(ControllerContext context)
{
var properties = new AuthenticationProperties { RedirectUri = RedirectUri };
if (UserId != null)
{
properties.Dictionary[XsrfKey] = UserId;
}
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, SocialAccountProvider);
}
как именно он используется для защиты?
должен ли я установить значение XsrfKey на что-то более случайное?
2 ответов
посмотри ManageController
методы LinkLogin
и LinkLoginCallback
:
//
// POST: /Manage/LinkLogin
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LinkLogin(string provider)
{
// Request a redirect to the external login provider to link a login for the current user
return new AccountController.ChallengeResult(provider, Url.Action("LinkLoginCallback", "Manage"), User.Identity.GetUserId());
}
//
// GET: /Manage/LinkLoginCallback
public async Task<ActionResult> LinkLoginCallback()
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId());
if (loginInfo == null)
{
return RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });
}
var result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login);
return result.Succeeded ? RedirectToAction("ManageLogins") : RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });
}
это методы, которые обрабатывают связывание внешних учетных записей (например, Google, Facebook и т. д.). Поток идет так:
- пользователь нажимает кнопку" связать учетную запись", которая вызывает сообщение в
LinkLogin
метод. -
LinkLogin
возвращаетChallengeResult
объект, с url обратного вызова установлен вLinkLoginCallback
метод. -
ChallengeResult.ExecuteResult
вызывается MVC framework, вызываетIAuthenticationManager.Challenge
, что вызывает перенаправление к конкретному внешнему поставщику входа в систему (скажем: google). - пользователь аутентифицируется с помощью google, затем google перенаправляет на url обратного вызова.
- обратный вызов обрабатывается с
LinkLoginCallback
. Здесь мы хотим предотвратить XSRF и проверить, что вызов был инициирован пользователем со страницы, обслуживаемой нашим сервером (а не каким-либо вредоносным сайтом).
обычно, если бы это была простая последовательность GET-POST, вы бы добавили скрытый параметр состояния в OAuth2 был разработан для.
вернемся к нашим XsrfKey
: все, что вы помещаете в AuthenticationProperties.Dictionary
будет быть сериализованы и включены в state
параметр запроса OAuth2-и, следовательно, обратный вызов OAuth2. Теперь,GetExternalLoginInfoAsync(this IAuthenticationManager manager, string xsrfKey, string expectedValue)
искать XsrfKey
в полученном государственном словаре и сравните его с expectedValue
. Он вернет ExternalLoginInfo
только если значения равны.
Итак, отвечая на ваш первоначальный вопрос: вы можете установить XsrfKey
на все, что вы хотите, пока тот же ключ используется при настройке и чтении. Это не имеет большого смысла, чтобы установить его на что-то случайное - the state
параметр зашифрован, поэтому никто не ожидает, что вы сможете прочитать его в любом случае.
просто оставьте его как есть:
в качестве названия государств-членов это ключ:
private const string XsrfKey = "XsrfId";
он определяется таким образом, чтобы избежать "магических чисел", а затем используется немного вниз в коде эшафота:
public override void ExecuteResult(ControllerContext context)
{
var properties = new AuthenticationProperties { RedirectUri = RedirectUri };
if (UserId != null)
{
properties.Dictionary[XsrfKey] = UserId;
}
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
}
значение элемента словаря затем устанавливается в свойство UserId в приведенном выше коде с помощью элемента XsrfKey в качестве ключа.
IOW код уже устанавливает для элемента словаря XSRF значение идентификатора пользователя в фрагменте. Если вы измените значение членов XsrfKey на что-либо еще, вы вызовете проблемы в строке, так как ожидаемый ключ "XsrfId" не будет иметь значения.
Если, изменив его на что-то более случайное, вы подразумеваете изменение значения, а не ключа словаря, или, другими словами, не устанавливаете его в идентификатор пользователя, то, пожалуйста, см. Следующее для объяснения внутреннего маркера анти-подделки горные выработки.
http://www.asp.net/mvc/overview/security/xsrfcsrf-prevention-in-aspnet-mvc-and-web-pages