Blazor 托管 WebAssembly 在 kubernetes 中具有多个副本,导致身份验证问题

问题描述 投票:0回答:1

我有一个在 .Net8 下用 Blazor WebAssembly 编写的应用程序。该应用程序是托管模型,这意味着有一个客户端和服务器项目。使用 Web api 进行相互通信。该应用程序正在使用身份验证和授权。

服务器程序.cs 文件

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.DataProtectionProvider = DataProtectionProvider.Create(Parameters.app_protector);
        options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
        options.SlidingExpiration = true;
        options.LoginPath = new PathString("/auth/login");
        options.LogoutPath = new PathString("/auth/logout");
        options.AccessDeniedPath = new PathString("/");
        options.Cookie = new CookieBuilder();
        options.Cookie.Name = Parameters.app_cookie;
        options.Cookie.MaxAge = options.ExpireTimeSpan;
        options.Cookie.SameSite = SameSiteMode.Strict; //TESTING WITH STRICT
        options.Cookie.SecurePolicy = CookieSecurePolicy.None;
        options.CookieManager = new ChunkingCookieManager();
        options.EventsType = typeof(CustomCookieAuthenticationEvents);
    });

app.UseAuthentication();
app.UseAuthorization();

用于登录的服务器控制器:

[HttpPost, Route("/api/auth/login")]
public IActionResult AuthLogin(Authentication authentication)
{
    try
    {
        int auth_id = _IAuth.AuthLogin(authentication); //VALIDATE INFO IN DATABASE
        if (auth_id != -1)
        {
            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Sid, auth_id.ToString()),
                new Claim(ClaimTypes.Name, authentication.user_name.ToString()),
            };
            var claimsIdentity = new ClaimsIdentity(claims, "Authentication");

            var properties = new AuthenticationProperties()
            {
                IsPersistent = true,
                AllowRefresh = true
            };

            HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), properties);
        }
        return Ok(auth_id); //RETURN A NUMBER GRATER FROM -1 TO SIGN IN
    }
    catch { throw; }
}

客户端中的身份验证是通过 CustomAuthStateProvider 处理的

HttpResponseMessage httpResponseMessage = await _httpClient.GetAsync("/api/auth/check");
if (httpResponseMessage.IsSuccessStatusCode)
{
    HttpContent content = httpResponseMessage.Content;
    AuthenticationData? authenticationData_ = await content.ReadFromJsonAsync<AuthenticationData?>();
    authenticationData = CheckAuthenticationData(authenticationData_);
    
    //HELPER MESSAGE FOR BROWSER
    if (authenticationData != null)
    { Console.WriteLine("user_is_authorized"); }
    else
    { Console.WriteLine("user_not_authorized"); }
}

从服务器控制器获取响应:

AuthenticationData? authenticationData = new AuthenticationData();
var authorizationResult = _authorizationService.AuthorizeAsync(User, UserPolicy).Result;
if (authorizationResult.Succeeded)
{
    authenticationData.Sid = User.Claims.Where(x => x.Type == ClaimTypes.Sid).Select(x => x.Value).FirstOrDefault().NStringToString();
    authenticationData.Name = User.Claims.Where(x => x.Type == ClaimTypes.Name).Select(x => x.Value).FirstOrDefault().NStringToString();

    HttpContext.AuthenticateAsync();
}
return authenticationData;

在本地、AzureWebApp 或 Kubernetes 集群中工作时一切正常,但是一旦我们以超过 1 的副本进行扩展,就会开始出现故障(在这种情况下,我用于某些消息的信号器方法失败了,而且身份验证也失败了) : ![enter image description here

我做了一些调查,我认为服务器保存了经过身份验证的用户的某种状态,因为不断刷新页面三(3)次中的一(1)次有效,并且考虑到副本设置为3,这是有道理的对我来说,kubernetes 可能会将 Round-Robin 引入到 loadbalancher 作为分配调用的默认方法。我还收到来自控制台的消息“user_not_authorized”: enter image description here

如果是对的,为什么服务器会保持某种状态? 或者我可能错过的任何其他想法??

authentication kubernetes blazor authorization scaleout
1个回答
0
投票

我相信这可能是由于错误的入口定义引起的,因为问题是从更多副本开始的。 您是否设置了粘性会话? https://learn.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/server?view=aspnetcore-8.0#kubernetes

© www.soinside.com 2019 - 2024. All rights reserved.