Asp.Net核心“记住我”持久性cookie在部署后无效

时间:2017-09-20 09:37:15

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

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

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

enter image description here

有人可以帮我解决这个问题吗?

预先感谢您的回复:)

编辑:

根据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
}

1 个答案:

答案 0 :(得分:9)

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

        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