Что такое 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 и т. д.). Поток идет так:

  1. пользователь нажимает кнопку" связать учетную запись", которая вызывает сообщение в LinkLogin метод.
  2. LinkLogin возвращает ChallengeResult объект, с url обратного вызова установлен в LinkLoginCallback метод.
  3. ChallengeResult.ExecuteResult вызывается MVC framework, вызывает IAuthenticationManager.Challenge, что вызывает перенаправление к конкретному внешнему поставщику входа в систему (скажем: google).
  4. пользователь аутентифицируется с помощью google, затем google перенаправляет на url обратного вызова.
  5. обратный вызов обрабатывается с 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