.net 每次在ECS中部署应用程序(使用Fargate)时,都提示用户重新通过Google(使用OIDC)进行身份验证

yftpprvb  于 2023-08-08  发布在  .NET
关注(0)|答案(1)|浏览(96)

我有一个使用AWS ECS Fargate托管的.Net 7 Web应用程序(在2个任务上运行)。我使用Google作为OIDC提供商,并且能够成功地对用户进行身份验证(本地和生产)。
我使用以下代码来实现这一点:

builder.Services.AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddCookie(options =>
    {
        options.Cookie.Name = "AppAuth";
        options.ExpireTimeSpan = TimeSpan.FromHours(12);
        options.SlidingExpiration = false;
        options.Events = new CookieAuthenticationEvents
        {
            OnValidatePrincipal = async context =>
            {
                var claimsPrincipal = context.Principal;
                var email = claimsPrincipal.FindFirstValue(ClaimTypes.Email);
                
                if (claimsPrincipal != null)
                {
                    var claimsIdentity = (ClaimsIdentity)claimsPrincipal.Identity;
                    if (claimsIdentity != null)
                    {
                        if (!claimsIdentity.HasClaim(x => x.Type == "user-id"))
                        {
                            var response = await api.GetUsersAsync(email: email);
                            claimsIdentity.AddClaim(new Claim("user-id", response.Users.Single().UserId.ToString()));
                        }
                        
                    }
                    await context.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal, context.Properties);
                }
            }
        };
    })
    .AddOpenIdConnect(options =>
    {
        options.Authority = "https://accounts.google.com";
        options.ClientId = "***";
        options.ClientSecret = "***";
        options.ResponseType = OpenIdConnectResponseType.Code;
        options.Scope.Add("openid");
        options.Scope.Add("email");
        options.GetClaimsFromUserInfoEndpoint = true;
        options.CallbackPath = "/oauth2/idpresponse";
        options.Events = new OpenIdConnectEvents
        {
            OnRedirectToIdentityProvider = context =>
            {
                if (!builder.Environment.IsDevelopment())
                {
                    var uriBuilder = new UriBuilder(context.ProtocolMessage.RedirectUri)
                    {
                        Scheme = "https",
                        Port = -1
                    };
                    context.ProtocolMessage.RedirectUri = uriBuilder.ToString();
                }
                return Task.FromResult(0);
            }
        };
    });

字符串
我遇到的问题是,每次我使用AWS ECS Fargate部署应用程序,然后刷新页面时,它都会将我重定向回Google登录页面。为了清楚起见,在Fargate上部署应用程序的过程包括启动两个新任务,然后销毁现有任务。
另一件值得一提的事情(可能相关)是,我打开了粘性会话(需要启用Redis背板才能让SignalR工作,see here)。
另一件可能值得一提的事情是我不能在本地复制它;当我重新启动我的应用程序,然后刷新页面,它保持登录的经验。

sqxo8psd

sqxo8psd1#

这可能是因为您的网站的cookie加密密钥在每次部署时都会重新生成为新值。因此,任何留在浏览器中的cookie一旦被新部署接收就无法解密,因此.NET触发新的登录重定向。
您应该能够通过使用浏览器工具查看请求和响应详细信息来验证是否发生了这种情况。如果使用Chrome,请使用preserve log option,以避免在Google重定向时丢失旧请求。
如果这确实是原因,解决方案是使用data protection options之一,例如将密钥持久化到redis或数据库,以确保在重新部署应用时使用相同的密钥。另请注意,默认情况下,密钥每90天回收一次,这将导致相同的cookie拒绝事件。

相关问题