【问题标题】:Asp.Net core "remember me" persistent cookie not works after deploy部署后 Asp.Net 核心“记住我”持久性 cookie 不起作用
【发布时间】:2018-03-01 07:15:59
【问题描述】:

我已经构建了一个 MVC Core(框架)应用程序,并使用 Identity 登录。 当我点击“记住我”选项时,在我的开发机器上一切正常,但在服务器机器上部署后,“记住我”在 30 分钟后无法保持登录。

我尝试检查是否设置了 cookie 到期日期并且似乎没问题,同样在服务器机器上,cookie 似乎设置得很好。 您可以在下图中查看我的 cookie 详细信息:

谁能帮我解决这个问题?

提前感谢您的回复:)

编辑:

根据 Orhun 的要求,我在 Startup.cs 内容下方添加:

public partial class Startup
{
    public SymmetricSecurityKey signingKey;

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        if (env.IsDevelopment())
        {
            // For more details on using the user secret store see https://go.microsoft.com/fwlink/?LinkID=532709
            builder.AddUserSecrets<Startup>();
        }

        builder.AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {

        ///////////////////////////
        // Custom Services - START
        ///////////////////////////

        string conn = CreateConnectionString(Configuration.GetConnectionString("TiesseWebConnection"));
        services.AddScoped<System.Data.Entity.DbContext>((_) => new TiesseWeb.DAL.TiesseWebEntities(conn));  //Configuration["Data:DefaultConnection:ConnectionString"]));


        // SESSION section
        services.AddMemoryCache();
        services.AddDistributedMemoryCache();
        services.AddSession();

        services.AddSingleton<IConfiguration>(Configuration);   // IConfiguration explicitly

        // Add functionality to inject IOptions<T> (important for inject Config object)
        services.AddOptions();


        // Add our Config object so it can be injected
        services.Configure<Settings>(Configuration.GetSection("Settings"));
        // Add our Config object so it can be injected
        services.AddScoped<Settings>();

        services.AddScoped<Tiesse.Web.BL.TiesseWebManager>();

        ///////////////////////////
        // Custom Services - END
        ///////////////////////////

        // Add framework services.
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("TiesseWebConnection")));


        services.AddIdentity<ApplicationUser, ApplicationRole>(i =>
        {
            i.SecurityStampValidationInterval = TimeSpan.FromDays(14);
            //i.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromDays(14);
        })
        //services.AddIdentity<ApplicationUser, ApplicationRole>()//IdentityRole>()
          .AddEntityFrameworkStores<ApplicationDbContext, int>()
          .AddDefaultTokenProviders();

        services.AddMvc().AddJsonOptions(jsonOptions =>
        {
            jsonOptions.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
        }); ;

        // Add application services.
        services.AddTransient<IEmailSender, AuthMessageSender>();
        services.AddTransient<ISmsSender, AuthMessageSender>();

        // Adds Authorizations
        services.AddAuthorization(options =>
        {
            options.AddPolicy("Admin", policy => policy.RequireClaim("Admin"));
            options.AddPolicy("Admin-Utenti", policy => policy.RequireClaim("Admin-Utenti"));
            options.AddPolicy("Admin-Filiali", policy => policy.RequireClaim("Admin-Filiali"));
            options.AddPolicy("Admin-Reparti", policy => policy.RequireClaim("Admin-Reparti"));
            options.AddPolicy("GoogleDrive", policy => policy.RequireClaim("GoogleDrive"));
            options.AddPolicy("GoogleDrive-Gestione", policy => policy.RequireClaim("GoogleDrive-Gestione"));
            options.AddPolicy("GoogleDrive-Gestione-Struttura", policy => policy.RequireClaim("GoogleDrive-Gestione-Struttura"));
            options.AddPolicy("GoogleDrive-Consultazione", policy => policy.RequireClaim("GoogleDrive-Consultazione"));
            options.AddPolicy("Reports", policy => policy.RequireClaim("Reports"));
            options.AddPolicy("Reports-Test", policy => policy.RequireClaim("Reports-Test"));
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        // Custom settings
        app.UseSession();

        //// configures Bearer token Authentication
        //ConfigureAuth(app);
        ///////////////////


        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            //app.UseDeveloperExceptionPage();
            //app.UseDatabaseErrorPage();
            //app.UseBrowserLink();
        }

        app.UseStaticFiles();

        app.UseIdentity();

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            //CookieName = "MyWebCookie",
            //CookieDomain = "http://devweb01:81",      // uncomment when deploy
            CookieHttpOnly = true,
            CookieSecure = CookieSecurePolicy.Always,
            ExpireTimeSpan = TimeSpan.FromDays(30),
            SlidingExpiration = true,
            AutomaticAuthenticate = true,
            AutomaticChallenge = true
            //AuthenticationScheme = "MyeWebCookie"
        });

        app.UseGoogleAuthentication(new GoogleOptions()
        {
            // following Goggle Secrets data have been hardcoded because Configuration with Secrets.json works only in development environment
            ClientId = "XXXXXXX....",
            ClientSecret = "XXXXXXX....",
            AutomaticAuthenticate = true
            //SignInScheme = "MyWebCookie"
        });

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

    #region Methods

    public static string CreateConnectionString(string providerConnectionString)
    {
        var entityBuilder = new EntityConnectionStringBuilder();

        // use your ADO.NET connection string
        entityBuilder.ProviderConnectionString = providerConnectionString;

        entityBuilder.Provider = "System.Data.SqlClient";

        // Set the Metadata location.
        entityBuilder.Metadata = @"res://*/TiesseWebDB.csdl|res://*/TiesseWebDB.ssdl|res://*/TiesseWebDB.msl";

        return entityBuilder.ConnectionString;
    }

    #endregion
}

【问题讨论】:

  • 你能分享你的 Startup.cs 文件吗?
  • 我理解你的意思吗,问题是通过取消注释 "CookieDomain" 解决的?我绞尽脑汁试图解决这个问题......
  • 嗨 dantey89,目前我没有解决问题。我认为这是与 Web 服务器机器有关的问题,因为我将我的 Web 应用程序部署在 2 台服务器上,并且在其中一台服务器上它可以工作,但我不明白为什么。你找到解决办法了吗?有什么建议?谢谢
  • 我将发布一个答案并描述我所做的事情。

标签: c# cookies asp.net-core asp.net-core-mvc


【解决方案1】:

我遇到了同样的问题。我解决了很久。但是几天前我找到了解决方案。正如您在 cmets 中提到的,问题是机器密钥。我不知道为什么,但应用程序每次重新启动时都会生成新的机器密钥。所以解决问题的方法是强制应用程序使用常量键。为此,您需要在启动时添加如下代码:

        public void ConfigureServices(IServiceCollection services)
        {

            var environment = services.BuildServiceProvider().GetRequiredService<IHostingEnvironment>();


            services.AddDataProtection()
                    .SetApplicationName($"my-app-{environment.EnvironmentName}")
                    .PersistKeysToFileSystem(new DirectoryInfo($@"{environment.ContentRootPath}\keys"));

           ...

        }

应用程序在“key”文件夹中启动后,您将找到包含您的机器密钥的 xml。更多详情您可以找到here

【讨论】:

  • 嗨 dantey89,太棒了,我按照您的说明和您发布的链接解决了我的问题。非常感谢你;)
  • SO 建议不要回答“谢谢”,但我会这样做。您的回答确实为我节省了很多时间。我不知道根本问题是什么,但已经在第二个项目中面对它 - 并且只在项目网站上
  • 嘿,这个答案解决了我的问题。我花了这么多小时。我什至花钱请人修理它。
  • 3.1 有什么问题?您可能面临的唯一问题是 IHostingEnvironment 已重命名为 IWebHostEnvironment
  • 文档中没有提到这一点,也没有包含在入门模板中,这真是令人气愤,浪费了这么多时间试图弄清楚为什么 auth cookie 会在 30 分钟后过期。
猜你喜欢
  • 2020-12-12
  • 1970-01-01
  • 1970-01-01
  • 2011-08-22
  • 2011-03-22
  • 1970-01-01
  • 1970-01-01
  • 2017-06-04
  • 1970-01-01
相关资源
最近更新 更多