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



我有一个 ASP.NET Core API \ Angular app。我的 API 需要支持 Cookie 和令牌。

使用我的服务登录后,返回的防伪令牌无效,因为它是基于空用户创建的。我尝试在我的密码登录异步之后设置声明主体并重新生成防伪令牌(见下文(,但这仍然不起作用。有什么想法吗?

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();
}

ASP.Net Core 2.2显然会有一个"推荐"的方法。

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

我没有使用Angular,但我使用的是Axios HTTP客户端,它具有相同的"读取cookie,写入标头"支持。因此,这没有用 Angular 进行测试,但它使用相同的 cookie 和标头名称。

我对此并不完全满意,因为感觉就像手动设置HttpContext.User一样......哈克。

我创建了一个 ResultFilterAction,它将在控制器操作运行后设置 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);
{...}
}

最后,需要向登录和注销操作添加一行,以确保设置了 HttpContext.User。

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

相关内容

  • 没有找到相关文章

最新更新