// 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的值设置为更随机吗?
解决方法
// // 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重定向到回调网址.
>回调由LinkLoginCallback处理.在这里,我们想防止XSRF,并验证该呼叫是由用户发起的,从我们的服务器(而不是某些恶意站点)提供的页面.
通常,如果它是一个简单的GET-POST序列,您将添加一个隐藏的< input>字段与防伪令牌,并将其与相应的cookie值进行比较(这就是Asp.Net Anti-Forgery Tokens的工作原理).
在这里,请求来自外部验证提供商(在我们的示例中为Google).所以我们需要把反伪造币给google,google应该把它放在回调请求中.这正是OAuth2设计的state parameter.
返回到我们的XsrfKey:将所有您在AuthenticationProperties.Dictionary中放置的内容都将被序列化并包含在OAuth2请求的状态参数中,从而导致OAuth2回调.现在,GetExternalLoginInfoAsync(此IAuthenticationManager管理器,字符串xsrfKey,string expectedValue)将在接收状态字典中查找XsrfKey并将其与expectedValue进行比较.只有当值相等时,它才会返回ExternalLoginInfo.
所以,回答你原来的问题:你可以设置XsrfKey到任何你想要的,只要在设置和阅读时使用相同的键.将它设置为随机的任何东西都没有什么意义 – 状态参数是加密的,所以没有人会希望你能够阅读它.