ASP.NET Core API - 登录和防伪令牌

问题描述 投票:2回答:1

我有一个ASP.NET Core API \ Angular应用程序。我的API需要支持cookie和令牌。

使用我的服务登录后,返回的防伪标记无效,因为它是基于空用户创建的。我尝试在PasswordSignInAsync之后设置ClaimsPrincipal并重新生成防伪令牌(见下文),但仍然无法正常工作。有任何想法吗?

public virtual async Task<IActionResult> Login([FromBody] AccountLoginModel model)
{
        var result = await this.SignInManager.PasswordSignInAsync(model.Email, model.Password, isPersistent: model.RememberMe, lockoutOnFailure: false);
        if (!result.Succeeded)
        {
            return this.BadRequest();
        }
        var user = await this.UserManager.FindByEmailAsync(model.Email);

        // Must manually set the HttpContext user claims to those of the logged
        // in user. Otherwise MVC will still include a XSRF token for the "null"
        // user and token validation will fail. (MVC appends the correct token for
        // all subsequent reponses but this isn't good enough for a single page
        // app.)
        var principal = await this.PrincipalFactory.CreateAsync(user);
        this.HttpContext.User = principal;

        // Update XSRF token
        var tokens = this.Antiforgery.GetAndStoreTokens(this.HttpContext);

        return this.Ok();
}
angularjs asp.net-core asp.net-identity antiforgerytoken
1个回答
0
投票

ASP.Net Core 2.2显然会有一个"recommended" approach

但在那之前,这就是我想出来的:https://github.com/aspnet/Home/issues/2783#issuecomment-422322294

我没有使用Angular,但我正在使用具有相同“读取cookie,写入标头”支持的Axios HTTP客户端。所以这不是使用Angular测试的,而是使用相同的cookie和标题名称。

我对它并不完全满意,因为感觉就像手动设置HttpContext.User相当......糟糕。

我创建了一个ResultFilterAction,它将在Controller Actions运行后设置cookie。灵感:https://github.com/aspnet/Home/issues/2415#issuecomment-354674201

public class AntiforgeryCookieResultFilterAttribute : ResultFilterAttribute
{
    protected IAntiforgery Antiforgery { get; set; }

    public AntiforgeryCookieResultFilterAttribute(IAntiforgery antiforgery) => this.Antiforgery = antiforgery;

    public override void OnResultExecuting(ResultExecutingContext context)
    {
        var tokens = this.Antiforgery.GetAndStoreTokens(context.HttpContext);
        context.HttpContext.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
    }
}

我在Startup.cs中把它搞定了:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAntiforgery(options =>
    {
        options.HeaderName = "X-XSRF-TOKEN";
    });

    services.AddTransient<AntiforgeryCookieResultFilterAttribute>();

    services
        //AJ: See above for more information about AntiForgeryTokens.
        .AddMvc(options =>
        {
            options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
            options.Filters.AddService<AntiforgeryCookieResultFilterAttribute>();
        })
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    {...}
}

最后,一行需要添加到Login和Logout操作以确保设置了HttpContext.User。

登录:HttpContext.User = await signInManager.CreateUserPrincipalAsync(user);退出:HttpContext.User = new ClaimsPrincipal();

© www.soinside.com 2019 - 2024. All rights reserved.