В Java эти конкретные классы реализуют интерфейс CharSequence:
CharBuffer, String, StringBuffer, StringBuilder
blockquote>Эти конкретные классы не имеют общего родительский класс, отличный от Object, поэтому нет ничего, что связывало бы их, кроме того, что каждый из них имеет какое-то отношение к массивам символов, представляющих такие или манипулирующие такими. Например, символы String не могут быть изменены после создания экземпляра объекта String, тогда как символы StringBuffer или StringBuilder могут быть отредактированы.
Однако каждый из этих классов способен соответствующим образом реализовать методы интерфейса CharSequence :
char charAt(int index) int length() CharSequence subSequence(int start, int end) String toString()
В некоторых случаях классы классов классов Java, которые использовали для приема String, были пересмотрены, чтобы теперь принять интерфейс CharSequence. Поэтому, если у вас есть экземпляр StringBuilder, вместо извлечения объекта String (что означает создание экземпляра нового объекта) вместо этого можно просто передать сам StringBuilder, поскольку он реализует интерфейс CharSequence.
Добавляемый интерфейс, который некоторые классы реализуют такую же выгоду для любой ситуации, когда символы могут быть добавлены к экземпляру конкретного конкретного экземпляра объекта класса. Все эти конкретные классы реализуют интерфейс Appendable:
BufferedWriter, CharArrayWriter, CharBuffer, FileWriter, FilterWriter, LogStream, OutputStreamWriter, PipedWriter, PrintStream, PrintWriter, StringBuffer, StringBuilder, StringWriter, Writer
blockquote>
Взгляните на методы 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, вызывает IAuthenticationManager.Challenge
, что вызывает перенаправление к определенному внешнему провайдеру входа (скажем: google). LinkLoginCallback
. Здесь мы хотим предотвратить XSRF и убедиться, что вызов был инициирован пользователем, со страницы, обслуживаемой нашим сервером (а не каким-то вредоносным сайтом). Обычно, если это была простая последовательность GET-POST, вы бы добавили скрытое поле <input>
с токеном анти-подделки и сравните его с соответствующим значением 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
зашифрован, поэтому никто не ожидает, что вы все равно сможете его прочитать.
Просто оставьте это как:
Как имя состояний-членов это ключ:
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