Ответ 1
Взгляните на методы 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 и т.д.). Поток выглядит следующим образом:
- Пользователь нажимает кнопку "Ссылка на учетную запись", которая вызывает метод POST до
LinkLogin
. -
LinkLogin
возвращает объектChallengeResult
, с URL-адресом обратного вызова, установленным вLinkLoginCallback
. -
ChallengeResult.ExecuteResult
вызывается инфраструктурой MVC, вызываетIAuthenticationManager.Challenge
, что вызывает перенаправление к определенному внешнему провайдеру входа (скажем: google). - Пользователь аутентифицируется с помощью Google, затем переадресовывает Google на URL-адрес обратного вызова.
- Обратный вызов обрабатывается с помощью
LinkLoginCallback
. Здесь мы хотим предотвратить XSRF и убедиться, что вызов был инициирован пользователем, со страницы, обслуживаемой нашим сервером (а не каким-то вредоносным сайтом).
Обычно, если это была простая последовательность GET-POST, вы должны добавить скрытое поле <input>
с токеном анти-подделки и сравнить его с соответствующим значением cookie (что как Асп. Интенсивные токены).
Здесь запрос поступает от внешнего поставщика авторизации (google в нашем примере). Поэтому нам нужно предоставить токен анти-подделки Google, а google должен включить его в запрос обратного вызова. То, что параметр состояния в OAuth2 был разработан для.
Вернемся к нашему XsrfKey
: все, что вы помещаете в AuthenticationProperties.Dictionary
, будет сериализовано и включено в параметр state
запроса OAuth2 - и, следовательно, обратный вызов OAuth2. Теперь GetExternalLoginInfoAsync(this IAuthenticationManager manager, string xsrfKey, string expectedValue)
будет искать XsrfKey
в полученном состоянии Словарь и сравнить его с expectedValue
. Он вернет ExternalLoginInfo
, только если значения равны.
Итак, отвечая на ваш первоначальный вопрос: вы можете установить XsrfKey
на все, что хотите, до тех пор, пока один и тот же ключ используется при настройке и чтении. Не имеет смысла устанавливать что-либо случайное - параметр state
зашифрован, поэтому никто не ожидает, что вы все равно сможете его прочитать.