Xsrf令牌与Jwt令牌冲突

时间:2018-09-12 08:27:43

标签: angular asp.net-core jwt x-xsrf-token

我正在使用带有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;
    }

我确定clienside应用程序将发送令牌: enter image description here

并且我使用了antiforgery.ValidateRequestAsync(HttpContext);获取确切的错误:

enter image description here

0 个答案:

没有答案