Проверка подлинности Cook ie не работает должным образом с проверкой подлинности JWT ASP. NET CORE - PullRequest
0 голосов
/ 15 января 2020

Я занимаюсь написанием веб-приложений с использованием ASP. NET CORE, и я столкнулся с проблемой идентификации. Я попытался выполнить поиск в Интернете, чтобы выяснить, не возникла ли у кого-то такая проблема, но безрезультатно.

Я создал простой веб-API, который использует JWT для аутентификации, и все работает отлично. Но мне нужно было также разрешить пользователям входить в систему с помощью форм, то есть аутентификации cook ie. Ниже приведен мой метод настройки служб.

private static void ConfigureJwt(IConfiguration configuration, IServiceCollection services)
        {
            services.AddSingleton<JwtSettings>();
            services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                }).AddCookie( conf =>
                {
                    conf.SlidingExpiration = true;
                    conf.LoginPath = "/account/login";
                    conf.LogoutPath = "/account/logout";
                })
                .AddJwtBearer(options =>
                {
                    options.SaveToken = true;
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey =
                            new SymmetricSecurityKey(Encoding.ASCII.GetBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")),
                        ValidateAudience = false,
                        ValidateIssuer = false,
                        RequireExpirationTime = false,
                        ValidateLifetime = true,
                        ClockSkew = TimeSpan.Zero,
                        ValidateActor = true

                    };
                });
        }

Итак, поскольку DefaultChallengeScheme установлен в «JwtBearerDefaults.AuthenticationScheme», я предположил, что, если я хочу авторизовать пользователя, который вошел в систему с использованием cook ie аутентификации, я должен просто указать схему аутентификации cook ie в этом конкретном методе контроллера, как показано ниже.

[Route("[controller]/[action]")]
    [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
    public class HomeController : Controller
    {
        // GET
        [HttpGet]
        public IActionResult Index()
        {
            return View();
        }
    }

Но меня всегда перенаправляют на страницу входа.

Единственный способ, которым я это работает, когда я удаляю настройки аутентификации по умолчанию

private static void ConfigureJwt(IConfiguration configuration, IServiceCollection services)
        {
            var jwtSettings = new JwtSettings();
            configuration.Bind(nameof(JwtSettings), jwtSettings);
            services.AddSingleton<JwtSettings>();
            services.AddAuthentication()
                .AddCookie( conf =>
                {
                    conf.SlidingExpiration = true;
                    conf.LoginPath = "/account/login";
                    conf.LogoutPath = "/account/logout";
                })
                .AddJwtBearer("jwt", options =>
                {
                    options.SaveToken = true;
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey =
                            new SymmetricSecurityKey(Encoding.ASCII.GetBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")),
                        ValidateAudience = false,
                        ValidateIssuer = false,
                        RequireExpirationTime = false,
                        ValidateLifetime = true,
                        ClockSkew = TimeSpan.Zero,
                        ValidateActor = true

                    };
                });
        }

Затем использую обычный атрибут [Authorize] для cook ie связанные маршруты

[Route("[controller]/[action]")]
    [Authorize]
    public class HomeController : Controller
    {
        // GET
        [HttpGet]
        public IActionResult Index()
        {
            return View();
        }
    }

Затем во всех моих API маршруты, я указал схему аутентификации JWT

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
        [HttpGet(ApiRoutes.Posts.GetAll)]
        public async Task<IActionResult> GetAll()
        {
            var posts = await _postService.GetAllAsync();
            return Ok(posts);
        }

Итак, мой вопрос, почему не сработала начальная конфигурация? И так как мое приложение в основном JWT использует аутентификацию, я хотел бы, чтобы оно было схемой аутентификации по умолчанию и указывало схему аутентификации cook ie только в нескольких методах контроллера, поскольку она используется редко. Это возможно? Если да, то как мне этого добиться?

1 Ответ

0 голосов
/ 16 января 2020

После дальнейших поисков я наткнулся на этот поток , который ответил на мой вопрос.

Я неправильно понял, как работает аутентификация в базовом приложении asp. net, которое использует идентификационные данные. , Когда вы используете Identity для аутентификации и входа в систему пользователя, используемая схема аутентификации по умолчанию называется «Identity.Applicaiton», а не «Cookies».

var result = await _signInManager.PasswordSignInAsync(loginModel.Email, loginModel.Password, true, false);

                if (result.Succeeded)
                {
                    return LocalRedirect("/home/index");
                }

Но если вы хотите использовать схему аутентификации «Cookies» Вы должны аутентифицировать и авторизовать пользователя, используя HttpContext.SignInAsyn c, как показано ниже, и явно выбрать «Cookies» в качестве схемы аутентификации.

var claims = new[]
                {
                    new Claim("email", user.Email),
                };
                var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
                    new ClaimsPrincipal(identity));
...