XsrfKey 的用途是什么,我应该将 XsrfId 设置为其他内容吗? [英] What is the XsrfKey used for and should I set the XsrfId to something else?

查看:15
本文介绍了XsrfKey 的用途是什么,我应该将 XsrfId 设置为其他内容吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 MVC 5 Web 应用程序中,我有这个(在 AccountController.cs 中):

In my MVC 5 web app I have this (in 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);
        }

它究竟是如何用于保护的?

How exactly is it being used for protection?

我应该将 XsrfKey 的值设置为更随机的值吗?

Should I set the value of XsrfKey to something more random?

推荐答案

看看 ManageController 方法 LinkLoginLinkLoginCallback:

Take a look at ManageController methods LinkLogin and 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 等)链接的方法.流程是这样的:

These are the methods that handle linking of external accounts (i.e. Google, Facebook, etc.). The flow goes like this:

  1. 用户单击链接帐户"按钮,该按钮调用 POST 到 LinkLogin 方法.
  2. LinkLogin 返回 ChallengeResult 对象,回调 url 设置为 LinkLoginCallback 方法.
  3. ChallengeResult.ExecuteResult 由 MVC 框架调用,调用 IAuthenticationManager.Challenge,这会导致重定向到特定的外部登录提供程序(假设:google).
  4. 用户通过谷歌进行身份验证,然后谷歌重定向到回调网址.
  5. 回调由 LinkLoginCallback 处理.在这里,我们想要阻止 XSRF 并验证调用是由用户从我们的服务器(而不是某个恶意站点)提供的页面发起的.
  1. User clicks "Link Account" button, which calls a POST to LinkLogin method.
  2. LinkLogin returns ChallengeResult object, with callback url set to LinkLoginCallback method.
  3. ChallengeResult.ExecuteResult is called by MVC framework, calls IAuthenticationManager.Challenge, which causes a redirect to the specific external login provider (let's say: google).
  4. User authenticates with google, then google redirects to callback url.
  5. The callback is handled with LinkLoginCallback. Here, we want to prevent XSRF and verify that the call was initiated by a user, from a page served by our server (and not by some malicious site).

通常,如果它是一个简单的 GET-POST 序列,您将添加一个带有防伪标记的隐藏 字段,并将其与相应的 cookie 值进行比较(这就是 Asp.Net 防伪令牌 工作).

Normally, if it was a simple GET-POST sequence, you would add a hidden <input> field with an anti-forgery token and compare it with a corresponding cookie value (that's how Asp.Net Anti-Forgery Tokens work).

此处,请求来自外部身份验证提供程序(在我们的示例中为 google).所以我们需要将防伪令牌提供给谷歌,谷歌应该将其包含在回调请求中.这正是 OAuth2 中的 状态参数专为.

Here, the request comes from external auth provider (google in our example). So we need to give the anti-forgery token to google and google should include it in the callback request. That's exactly what state parameter in OAuth2 was designed for.

回到我们的XsrfKey:你放入AuthenticationProperties.Dictionary 的所有内容都将被序列化并包含在OAuth2 请求的state 参数中 - 和因此,OAuth2 回调.现在,GetExternalLoginInfoAsync(this IAuthenticationManager manager, string xsrfKey, string expectedValue) 将在接收到的状态字典中查找 XsrfKey 并将其与 expectedValue 进行比较>.仅当值相等时,它才会返回 ExternalLoginInfo.

Back to our XsrfKey: everything you put in AuthenticationProperties.Dictionary will be serialized and included in the state parameter of OAuth2 request - and consequentially, OAuth2 callback. Now, GetExternalLoginInfoAsync(this IAuthenticationManager manager, string xsrfKey, string expectedValue) will look for the XsrfKey in the received state Dictionary and compare it to the expectedValue. It will return an ExternalLoginInfo only if the values are equal.

因此,回答您最初的问题:您可以将 XsrfKey 设置为任何您想要的值,只要在设置和读取时使用相同的键即可.将其设置为任何随机值并没有多大意义 - state 参数是加密的,因此没有人期望您无论如何都能读取它.

So, answering your original question: you can set XsrfKey to anything you want, as long as the same key is used when setting and reading it. It doesn't make much sense to set it to anything random - the state parameter is encrypted, so no one expect you will be able to read it anyway.

这篇关于XsrfKey 的用途是什么,我应该将 XsrfId 设置为其他内容吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆