Xsrf Token конфликтует с Jwt Token - PullRequest
0 голосов
/ 12 сентября 2018

Я использую Angular v6 с шаблоном asp.net core webapi. Я хочу отправить Xsrf Token в угловое приложение вместе с Identity Authorization моя проблема начинается, когда пользователь входит в систему. если в 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;
    }

Я уверен, что клиентское приложение отправит токен: enter image description here

и я использовал antiforgery.ValidateRequestAsync (HttpContext); для получения точной ошибки:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...