我正在使用带有ASP.NET Core WebAPI模板的angular v6 我想将Xsrf令牌与身份授权一起发送到angular应用 我的问题在用户登录时开始。如果HttpContext.User中没有用户 令牌没有问题,但是当用户登录并重新生成令牌时,我的所有发布请求都失败,状态码为400(由于无效的Xsrf令牌) 这是服务我的配置:
services.Configure<ApiSettings>(options => Configuration.GetSection("ApiSettings").Bind(options));
services.AddAuthentication(options =>
{
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Audience = "Any";
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = "http://localhost:44330/",
ValidAudience = "http://localhost:44330/",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("VeryStrongKey#123"))
};
});
services.AddIdentity<User, Role>();
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "/Ui";
});
services.AddAntiforgery(x => { x.HeaderName = "X-XSRF-TOKEN";x.Cookie.Name = "XSRF-TOKEN"; });
services.AddMvc(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
var builder = new ContainerBuilder();
services.AddScoped<IAntiForgeryCookieService, AntiForgeryCookieService>();
services.AddScoped<ITokenStoreService, TokenStoreService>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Populate(services);
builder.RegisterModule(new ManagementService.Service.DiRegister());
return new AutofacServiceProvider(builder.Build());
和我的应用配置:
app.UseStaticFiles();
app.UseSpaStaticFiles();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
loggerFactory.AddConsole(this.Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseAuthentication();
app.UseMvc();
app.UseSpa(spa =>
{
spa.Options.SourcePath = "Ui";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
在成功登录事件之后,我将如何生成用户声明:
public async Task<(string AccessToken, List<Claim> claims)> createAccessTokenAsync(User user,List<string> roles)
{
var claims = new List<Claim>
{
// Unique Id for all Jwt tokes
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString(), ClaimValueTypes.String, "http://localhost:44330/"),
// Issuer
new Claim(JwtRegisteredClaimNames.Iss, "http://localhost:44330/", ClaimValueTypes.String, "http://localhost:44330/"),
// Issued at
new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64, "http://localhost:44330/"),
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString(), ClaimValueTypes.String, "http://localhost:44330/"),
new Claim(ClaimTypes.Name, user.UserName, ClaimValueTypes.String, "http://localhost:44330/"),
new Claim("DisplayName", user.Firstname + " " + user.LastName, ClaimValueTypes.String, "http://localhost:44330/"),
// new Claim(ClaimTypes.SerialNumber, user.SerialNumber, ClaimValueTypes.String, "http://localhost:44330/"),
new Claim(ClaimTypes.UserData, user.Id.ToString(), ClaimValueTypes.String, "http://localhost:44330/")
};
// add roles
//var roles = await _rolesService.FindUserRolesAsync(user.Id);
foreach (var role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role, ClaimValueTypes.String, "http://localhost:44330/"));
}
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("VeryStrongKey#123"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var now = DateTime.UtcNow;
var token = new JwtSecurityToken(
issuer: "http://localhost:44330/",
audience: "http://localhost:44330/",
claims: claims,
notBefore: now,
expires: now.AddMinutes(20),
signingCredentials: creds);
return (new JwtSecurityTokenHandler().WriteToken(token), claims);
}
和创建索赔后的代币再生:
public string RegenerateAntiForgeryCookies(ClaimsPrincipal claims)
{
var httpContext = _contextAccessor.HttpContext;
httpContext.User = claims;
// httpContext.SignInAsync(claims);
var tokens = _antiforgery.GetAndStoreTokens(httpContext);
DeleteAntiForgeryCookies();
httpContext.Response.Cookies.Append(
key: XsrfTokenKey,
value: tokens.RequestToken,
options: new CookieOptions
{
HttpOnly = false // Now JavaScript is able to read the cookie
});
return tokens.RequestToken;
}
并且我使用了antiforgery.ValidateRequestAsync(HttpContext);获取确切的错误: