Аутентификация через CORS не устанавливает HttpContext.User

в настоящее время я столкнулся со следующей проблемой: я использую CORS для аутентификации через API JavaScript Fetch для моего ASP.NET-CORE 2.2 WebAPI. Для этого я использую следующий код:

const resp = await fetch(url, {
    method: 'POST',
    credentials: 'include',
    mode: 'cors'
});

где url содержит ссылку на мой вызов API входа.

Вызов входа выглядит следующим образом:

[HttpPost]
[Route("Login/{username}/{password}")]
[AllowAnonymous]
public async Task<IActionResult> Login(string username, string password)
{
    var theUser = await userManager.FindByNameAsync(username);
    if (theUser == null)
    {
        return BadRequest(userNotExistingMessage);
    }
    var result = await signInManager.PasswordSignInAsync(theUser, password, false, false);
    if (result.Succeeded)
    {
       return Ok(loginMessage);
    } else
    {
       return BadRequest(wrongPasswordMessage);
    }
}

Запуск.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy("AllowAll", builder =>
        {
            builder
            .AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials();
        });
    });

    // Authentication
    services.AddAuthentication(sharedOptions =>
    {
       sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    })
    .AddCookie(
    CookieAuthenticationDefaults.AuthenticationScheme,
    options =>
    {
        options.LoginPath = "/api/account/Login";
        options.Cookie.Name = "AUTHCOOKIE";
        options.ExpireTimeSpan = new TimeSpan(365, 0, 0, 0);
        options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
        options.Cookie.SameSite = SameSiteMode.None;
    });

    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => false;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    // DB
    services.AddDbContext<ApplicationDbContext>(options => options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddDefaultTokenProviders()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    // Sessions
    services.AddDistributedMemoryCache();
    services.AddSession(options =>
    {
        options.IdleTimeout = TimeSpan.FromMinutes(20);
        options.Cookie.SameSite = SameSiteMode.None;
        options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
        options.Cookie.IsEssential = true;
    });

    services.AddMvc()
        .AddJsonOptions(options =>
        {
            options.SerializerSettings.Formatting = Formatting.Indented;
        }
    );
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseCors("AllowAll");

    // Authorization
    var cookiePolicyOptions = new CookiePolicyOptions
    {
        Secure = CookieSecurePolicy.SameAsRequest,
        MinimumSameSitePolicy = SameSiteMode.None
    };
    app.UseCookiePolicy(cookiePolicyOptions);

    // Session
    app.UseSession();
    app.Use((httpContext, nextMiddleware) =>
    {
        httpContext.Session.SetString(SessionVariables.CID, httpContext.Session.Id);
        return nextMiddleware();
    });

    app.UseMvc();
}

Когда я добавляю Swagger и получаю доступ к Login, все работает нормально: после входа пользователя с PasswordSignInAsync() устанавливается HttpContext.User, и к нему можно получить доступ при дальнейшей работе с API. Но когда я пытаюсь получить доступ к своему API из javascript с помощью ранее показанной выборки, кажется, что HttpContext.User не устанавливается. Вот почему я не могу получить доступ ни к одному из его свойств, которые мне нужны.

Я пробовал разные вещи, чтобы получить эту работу, но ничего не получилось. Это сводит меня с ума. Есть ли кто-нибудь, кто может помочь мне решить эту проблему?


person M. Mustermann    schedule 21.01.2019    source источник


Ответы (1)


Возможно, настройки безопасности запрещают JavaScript доступ к файлам cookie.

Вы можете попробовать и посмотреть, работает ли следующее (HttpOnly to None):

var cookiePolicyOptions = new CookiePolicyOptions
{
 Secure = CookieSecurePolicy.SameAsRequest,
 MinimumSameSitePolicy = SameSiteMode.None,
 //Try setting this
 HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.None
};

И/или (options.Cookie.HttpOnly = false):

 services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            })
    .AddCookie(
    CookieAuthenticationDefaults.AuthenticationScheme,
    options =>
    {
        options.LoginPath = "/api/account/Login";
        options.Cookie.Name = "AUTHCOOKIE";
        options.ExpireTimeSpan = new TimeSpan(365, 0, 0, 0);
        options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
        options.Cookie.SameSite = SameSiteMode.None;
        options.Cookie.HttpOnly = false; // Try this
    });
person Phantom2018    schedule 21.01.2019
comment
Спасибо за ваш ответ. Я пробовал решение, но, к сожалению, оно не работает для меня. В любом случае, я нашел обходной путь (который меня не очень устраивает, но пока работает): я могу сохранить уникальный идентификатор пользователя в его файле cookie сеанса после того, как он вошел в систему, и использовать его для доступа к своим данным. - person M. Mustermann; 22.01.2019