【问题标题】:Cookie authentication issue ASP.NET CORE 2.1. AWS load balancingCookie 身份验证问题 ASP.NET CORE 2.1。 AWS 负载均衡
【发布时间】:2019-01-31 17:10:27
【问题描述】:

更新:下面的代码似乎失败了:

services.AddDataProtection()
            .SetApplicationName(appname)
            .PersistKeysToRedis(redis, "DataProtectionKeys")
            .ProtectKeysWithCertificate(LoadCert(Configuration));

无法从 pfx 文件中读取证书。

更新 2: 天啊! .gitignore 已排除证书文件!:)) Live&Learn。至少我们还活着,对吧!?;))


最初的问题: 我在 Docker 容器中的 AWS 负载均衡器后面部署了 ASP.NET Core 2.1 应用程序。 当我尝试从登录页面登录应用程序时。我得到了 InvalidOperationException 的理由:

没有指定 authenticationScheme,也没有 找到 DefaultChallengeScheme。

但是当我再次点击相同的 URL 时,它实际上移动到正确的页面并工作了一段时间,然后再次抛出相同的异常,HTTP 状态为 500 并在第二次尝试打开同一页面后成功。有趣的是,Chrome 不如 IE 健壮:如果 IE 在异常后无法恢复,Chrome 总是在随后提交页面时返回 404,从而产生上述异常。

因此,如果有人能够为我提供 想法如何补救这种情况显然问题与 身份验证,但我不知道应该做什么。

这里是 Startup.cs 中 ConfigureServices() 的相关操作:

        string appname = "MyApp";
        var redis = ConnectionMultiplexer.Connect(Configuration.GetConnectionString("RedisConnection"));
        services.AddDataProtection()
            .SetApplicationName(appname)
            .PersistKeysToRedis(redis, "DataProtectionKeys")
            .ProtectKeysWithCertificate(LoadCert(Configuration));

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        services.AddAuthentication( CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
                    options =>
                    { 
                        options.LoginPath = new PathString("/Area/Ctrl/Login");
                        options.LogoutPath = new PathString("/Area/Ctrl/Logout");
                        options.Cookie.IsEssential = true;
                    });

        services.AddDistributedRedisCache(o =>
        {
            o.Configuration = Configuration.GetConnectionString("RedisConnection");
        });
        services.AddSession(options =>
        {
            options.Cookie.Name = appname;
            options.IdleTimeout = TimeSpan.FromSeconds(600);
        });

这是 Startup.cs 中 Configure() 的相关代码:

        app.UseForwardedHeaders();
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseAuthentication();
        app.UseSession();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
             name: "areas",
             template: "{area:exists}/{controller=Ctrl}/{action=Login}/{id?}"
           );
        }); 

这是我在控制器中设置主体的方式,它处理登录:

            ClaimsIdentity identity = new ClaimsIdentity(GetUserRoleClaims(dbUserData), CookieAuthenticationDefaults.AuthenticationScheme);
            ClaimsPrincipal principal = new ClaimsPrincipal(identity);
            if (principal == null)
                throw new ApplicationException($"Could not create principal for {user?.UserName} user.");

            await httpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
            if (httpContext.User == null)
            {
                httpContext.User = principal;
            }

【问题讨论】:

    标签: c# amazon-web-services authentication asp.net-core-2.1


    【解决方案1】:

    好的,现在一切正常。:) 这就是与众不同的原因:

    1. 如果应用处于负载平衡状态,所有实例必须共享数据保护加密密钥(例如,使用相同的密钥环)。因此出现了 Redis 和证书。会话也应该共享。于是 Redis 又来了。

    2. ProtectKeysWithCertificate() 调用的证书应正确加载。如果无法加载,则根本不要进行该调用,但这确实是个坏主意。只要弄清楚为什么它没有加载。

    3. 为了避免在自定义身份验证 HttpContext 中引发 InvalidOperationException。用户应在登录操作中手动分配。

    关于证书的重要一点:数据保护模块仅支持带有 CAPI 私钥的证书。 CNG的被抛在后面。

    【讨论】:

      猜你喜欢
      • 2018-12-30
      • 1970-01-01
      • 2018-07-06
      • 1970-01-01
      • 2018-12-04
      • 2017-03-30
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      相关资源
      最近更新 更多