简体   繁体   English

Asp.Net Core:在 Web Farm 中共享身份验证 cookies 不起作用

[英]Asp.Net Core: Sharing authentication cookies in Web Farm doesn't work

I have an ASP.NET Core 3.1 application that uses cookie authentication and runs on a web farm.我有一个 ASP.NET Core 3.1 应用程序,它使用 cookie 身份验证并在 web 场上运行。 I want the application to share authenticated cookies between web servers.我希望应用程序在 web 服务器之间共享经过身份验证的 cookies。 The issue is when I log in on Server A through the load balancer the next ajax request from Server B redirects back to the login page.问题是当我通过负载平衡器登录服务器 A 时,来自服务器 B 的下一个 ajax 请求重定向回登录页面。 (Status Code 302, Set-Cookie: .AspNet.SharedCookie=;) (状态代码 302,设置 Cookie:.AspNet.SharedCookie=;)

If I log in directly to Server A and navigate pages - it works fine.如果我直接登录到服务器 A 并导航页面 - 它工作正常。 So my suspicions are that Server B does not validate cookies generated by Server A. Here is configuration of DataProtection:所以我怀疑服务器 B 没有验证服务器 A 生成的 cookies。这是 DataProtection 的配置:

services.AddDataProtection(options =>
            {
                options.ApplicationDiscriminator = "MyApp";
            })
            .PersistKeysToFileSystem(new DirectoryInfo(GetKeysPath()))
            .SetApplicationName("MyApp")
            .SetDefaultKeyLifetime(TimeSpan.FromDays(365));  

And authentication:和认证:

services
            .AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie(options =>
            {
                options.LoginPath = "/Login/Login";
                options.LogoutPath = "/Login/Logout";
                options.ReturnUrlParameter = "returnUrl";
                options.Cookie.Name = ".AspNet.SharedCookie";
                options.Cookie.Path = "/";
                options.Cookie.IsEssential = true;
                options.Cookie.HttpOnly = true;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
            });

Does anybody know what I'm missing?有人知道我错过了什么吗?

PSInitial issue I had with DataProtection, each server generated it's own keys so that other servers could not decrypt cookies and anti-forgery tokens. PSInitial 问题我遇到了 DataProtection,每台服务器都生成了自己的密钥,因此其他服务器无法解密 cookies 和防伪令牌。 So I copied the same key file to each server and the issue disappeared.所以我将相同的密钥文件复制到每台服务器,问题就消失了。

Links I used:我使用的链接:

Share Cookies Between Applications 在应用程序之间共享 Cookies

Configure Data Protection 配置数据保护

I found the root cause of the issue, the problem was not in DataProtection, Authentication or Cookies.我找到了问题的根本原因,问题不在于 DataProtection、Authentication 或 Cookies。 The problem was with Session, it used memory to store sessions so other servers (except which created) didn't know anything about the session.问题出在 Session 上,它使用 memory 来存储会话,因此其他服务器(创建的服务器除外)对 session 一无所知。 So I added storing session in database, like this one:所以我在数据库中添加了存储 session ,如下所示:

services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = 
        _config["DistCache_ConnectionString"];
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

and finally, my web farm is working fine.最后,我的 web 农场工作正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM