【问题标题】:The provided antiforgery token was meant for a different claims-based user than the current user提供的防伪令牌适用于与当前用户不同的基于声明的用户
【发布时间】:2017-04-11 19:25:00
【问题描述】:

我正在推出自己的身份验证系统,并且只使用我需要的位。我的解决方案基于this github repo。我已经审查了类似的问题,但它们似乎不适合我的情况。我也读过this post about Authentication and JWT,但我也不确定这是否相关。我迷路了。

我的 Startup.cs:

app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationScheme = "Cookies",
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            LoginPath = new PathString("/auth/login")
        });

        app.UseClaimsTransformation(context =>
        {
            if (context.Principal.Identity.IsAuthenticated)
            {
                context.Principal.Identities.First().AddClaim(new Claim("now", DateTime.Now.ToString()));
            }

            return Task.FromResult(context.Principal);
        });

我的身份验证控制器按预期工作。这是我使用 [ValidateAntiForgeryToken] 的登录操作;但是,整个 Controller 设置为 [AllowAnonymous]:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(LoginViewModel viewModel, string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;

        if (ModelState.IsValid)
        {
            var result = await _userManager.LoginUserAsync(viewModel.UserName, viewModel.Password, viewModel.RememberMe);
            if (result.Success)
            {
                // TODO: Log successful login

                var claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, result.User.FullName),
                    new Claim(ClaimTypes.Email, result.User.Email)
                };

                foreach(var role in result.User.Roles)
                {
                    claims.Add(new Claim(ClaimTypes.Role, role.Name));
                }

                var identity = new ClaimsIdentity(claims, "password");
                var principal = new ClaimsPrincipal(identity);

                await HttpContext.Authentication.SignInAsync("Cookies", principal);

                return LocalRedirect(returnUrl);
            }
            else
            {
                AddModelErrors(result);
                return View(viewModel);
            }
        }

        // Doh!
        return View(viewModel);
    }

到目前为止,一切都很好。

这是我得到错误的地方(400 Bad Request)。在 Create (Post) 方法中:

[Authorize(Roles = "Admin")]
public class UserAdministrationController : Controller
{
    private readonly IUserManager _userManager;
    private readonly IUserAdminViewModelFactory _userAdminViewModelFactory;

    public UserAdministrationController(
        IUserManager userManager,
        IUserAdminViewModelFactory userAdminViewModelFactory
        )
    {
        _userManager = userManager ?? throw new ArgumentNullException(nameof(userManager));
        _userAdminViewModelFactory = userAdminViewModelFactory ?? throw new ArgumentNullException(nameof(userAdminViewModelFactory));
    }


    [HttpGet]
    public IActionResult Index()
    {
        var userViewModels = _userAdminViewModelFactory.CreateUserViewModelList();
        return View(userViewModels);
    }

    [HttpGet]
    public IActionResult Create()
    {
        var createUserViewModel = _userAdminViewModelFactory.CreateUserViewModel();
        return View(createUserViewModel);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult Create(CreateUserViewModel viewModel)
    {
        return View();
    }
}

实际上,该方法永远不会因为这个错误而触发:

Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException:
提供的防伪令牌适用于不同的基于声明的用户 比当前用户。 在 Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery.ValidateTokens(HttpContext httpContext, AntiforgeryTokenSet antiforgeryTokenSet) 在 Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery.d__9.MoveNext()

如果我删除 [ValidateAntiForgeryToken],我不会收到错误消息;但是,如果我删除 [Authorize(Roles = "Admin")] 属性,我仍然会收到错误消息。

我想我“搞砸了一些平凡的细节”之类的,但不确定在哪里。

【问题讨论】:

  • 您是否使用 AJAX 请求登录?如果是这样,您需要在成功登录后刷新包含 AF 令牌的页面,因为该令牌最初是为匿名用户生成的,而您在登录后不再是该用户。

标签: asp.net-core-mvc


【解决方案1】:

尝试在构建防伪令牌之前设置用户,因为防伪令牌是使用用户声明构建的。

...
await HttpContext.Authentication.SignInAsync("Cookies", principal);
HttpContext.User = principal;
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-01
    • 2018-01-12
    • 1970-01-01
    • 2015-02-01
    • 2016-03-19
    • 2013-12-18
    • 2020-05-31
    • 2013-02-04
    相关资源
    最近更新 更多