代码之家  ›  专栏  ›  技术社区  ›  Mohammad Reza Farahani

Xsrf令牌与Jwt令牌冲突

  •  0
  • Mohammad Reza Farahani  · 技术社区  · 8 年前

    我正在使用带有asp.net核心webapi模板的angular v6 我想将Xsrf令牌和身份授权一起发送到angular应用程序 我的问题从用户登录时开始如果HttpContext.user中没有用户 令牌没有问题,但是当用户登录并重新生成令牌时,所有post请求都失败,状态代码为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 回复  |  直到 8 年前
    推荐文章