Как добавить обратный вызов для методов $ resource в AngularJS

Взгляните на методы 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 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. Пользователь нажимает кнопку «Ссылка на учетную запись», которая вызывает метод POST на LinkLogin.
  2. LinkLogin возвращает объект ChallengeResult с URL-адресом обратного вызова, установленным в LinkLoginCallback.
  3. ChallengeResult.ExecuteResult вызывается каркасом MVC, вызывает IAuthenticationManager.Challenge, что вызывает перенаправление к определенному внешнему провайдеру входа (скажем: google).
  4. Пользователь аутентифицируется с помощью google, затем переадресовывает Google на URL обратного вызова.
  5. Обратный вызов обрабатывается с помощью LinkLoginCallback. Здесь мы хотим предотвратить XSRF и убедиться, что вызов был инициирован пользователем, со страницы, обслуживаемой нашим сервером (а не каким-то вредоносным сайтом).

Обычно, если это была простая последовательность GET-POST, вы бы добавили скрытое поле с токеном анти-подделки и сравните его с соответствующим значением cookie (вот как Asp.Net Anti-Forgery Tokens работает).

Здесь запрос поступает от внешнего поставщика авторизации (google в нашем примере). Поэтому нам нужно предоставить токен анти-подделки Google, а google должен включить его в запрос обратного вызова. Это точно, какой параметр состояния состояния для OAuth2 был разработан.

Вернемся к нашему XsrfKey: все, что вы ввели AuthenticationProperties.Dictionary, будет сериализовано и включено в параметр state запроса OAuth2 - и, следовательно, обратного вызова OAuth2. Теперь GetExternalLoginInfoAsync(this IAuthenticationManager manager, string xsrfKey, string expectedValue) будет искать XsrfKey в полученном словаре состояния и сравнить его с expectedValue. Он вернет значение ExternalLoginInfo, только если значения равны.

Итак, отвечая на ваш исходный вопрос: вы можете установить XsrfKey на все, что хотите, до тех пор, пока один и тот же ключ используется при настройке и прочитав его. Не имеет смысла указывать на что-либо случайное - параметр state зашифрован, поэтому никто не ожидает, что вы все равно сможете его прочитать.

30
задан Edward 13 December 2012 в 03:25
поделиться