【问题标题】:Cookie authentication not working properly with JWT authentication ASP.NET CORECookie 身份验证无法与 JWT 身份验证 ASP.NET CORE 一起正常工作
【发布时间】:2020-05-01 21:44:52
【问题描述】:

我正在练习使用 ASP.NET CORE 编写 Web 应用程序,但遇到了 Identity 问题。我尝试在网上搜索,看看有没有其他人遇到过这样的问题,但无济于事。

我已经构建了一个简单的 web api,它使用 JWT 进行身份验证,并且一切正常。但我还需要允许用户使用表单登录,即 cookie 身份验证。以下是我的配置服务方法。

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”,我假设,如果我想授权使用 cookie 身份验证登录的用户,我应该只在该特定控制器方法中指定 cookie 身份验证方案,如下所示.

[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

                    };
                });
        }

然后在 cookie 相关路由上使用普通的 [Authorize] 属性

[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 身份验证,因此我希望它成为默认的身份验证方案,并且只在少数控制器方法中指定 cookie 身份验证方案,因为它很少使用。这可能吗?如果是,我该如何实现?

【问题讨论】:

    标签: asp.net-core cookies jwt asp.net-identity identity


    【解决方案1】:

    经过更多挖掘,我偶然发现了这个thread,它回答了我的问题。

    我误解了身份验证在使用身份的 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.SignInAsync 对用户进行身份验证和登录,如下所示,并明确选择“Cookies”作为您的身份验证方案。

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

    【讨论】:

      猜你喜欢
      • 2018-09-02
      • 2017-03-30
      • 2019-09-06
      • 2021-04-20
      • 1970-01-01
      • 2017-09-11
      • 2018-02-24
      • 1970-01-01
      • 2015-09-13
      相关资源
      最近更新 更多