Сохранение сеанса пользователя в Redis с помощью ASP.NET Core в Azure

Я использую кеш Redis для сохранения некоторых вещей в моем проекте.

Я использую Azure (WebApp), и когда я выполняю SWAP между моей предварительной средой и рабочей средой, сеанс пользователя теряется, и ему нужно повторно войти на мою веб-страницу.

Я использую Identity 3.0 с UseCookieAuthentication. Я хотел бы сохранить «сеанс» в Redis для решения моей проблемы, когда я выполняю обмен.

Я не нашел информации об этом, есть идеи? Спасибо

Код Startup.cs ConfigureServices:

public void ConfigureServices(IServiceCollection services)
        {

                        // Add framework services.
            services.AddApplicationInsightsTelemetry(Configuration);

            // Registers MongoDB conventions for ignoring default and blank fields
            // NOTE: if you have registered default conventions elsewhere, probably don't need to do this
            //RegisterClassMap<ApplicationUser, IdentityRole, ObjectId>.Init();

            AutoMapperWebConfiguration.Configure();

            services.AddSingleton<ApplicationDbContext>();

            // Add Mongo Identity services to the services container.
            services.AddIdentity<ApplicationUser, IdentityRole>(o =>
            {
                // configure identity options
                o.Password.RequireDigit = false;
                o.Password.RequireLowercase = false;
                o.Password.RequireUppercase = false;
                o.Password.RequireNonLetterOrDigit = false;
                o.Password.RequiredLength = 6;
                o.User.RequireUniqueEmail = true;
                o.Cookies.ApplicationCookie.CookieSecure = CookieSecureOption.SameAsRequest;
                o.Cookies.ApplicationCookie.CookieName = "MyCookie";
            })
                .AddMongoStores<ApplicationDbContext, ApplicationUser, IdentityRole>()
                .AddDefaultTokenProviders();

            services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromMinutes(60);
                options.CookieName = "MyCookie";
            });

            services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));

            services.AddLocalization(options => options.ResourcesPath = "Resources");

            // Caching This will add the Redis implementation of IDistributedCache
            services.AddRedisCache();

            services.Configure<RedisCacheOptions>(options =>
            {
                options.Configuration = Configuration["RedisConnection"];
            });




            services.AddCaching();

            // Add MVC services to the services container.
            services.AddMvc(options =>
            {
                options.CacheProfiles.Add("OneDay",
                    new CacheProfile()
                    {
                        Duration = 86400,
                        Location = ResponseCacheLocation.Any
                    });

                options.CacheProfiles.Add("OneMinute",
                    new CacheProfile()
                    {
                        Duration = 60,
                        Location = ResponseCacheLocation.Any
                    });

            })
                .AddViewLocalization(options => options.ResourcesPath = "Resources")
                .AddDataAnnotationsLocalization();



            services.Configure<AppOptions>(Configuration.GetSection("AppOptions"));



        }

Код Startup.cs

// 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)
        {
            //
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            app.UseApplicationInsightsRequestTelemetry();

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

            }

            app.UseSession();

            app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear());

            app.UseApplicationInsightsExceptionTelemetry();

            app.UseStaticFiles();

            app.UseIdentity();


            app.UseCookieAuthentication(options =>
            {
                options.AutomaticAuthenticate = true;
                options.LoginPath = new PathString("/Account/Login");
                options.AutomaticChallenge = true;
            });

            var requestLocalizationOptions = new RequestLocalizationOptions
            {
                // Set options here to change middleware behavior
                SupportedCultures = new List<CultureInfo>
                {
                    new CultureInfo("en-US"),
                    new CultureInfo("es-ES")
                },
                SupportedUICultures = new List<CultureInfo>
                {
                    new CultureInfo("en-US"),
                    new CultureInfo("es-ES")

                },
                RequestCultureProviders = new List<IRequestCultureProvider>
                {
                    new CookieRequestCultureProvider
                    {
                        CookieName = "_cultureLocalization"
                    },
                    new QueryStringRequestCultureProvider(),
                    new AcceptLanguageHeaderRequestCultureProvider
                    {

                    }

                }
            };

            app.UseRequestLocalization(requestLocalizationOptions, defaultRequestCulture: new RequestCulture("en-US"));

            app.UseFacebookAuthentication(options =>
            {
                options.AppId = "*****";
                options.AppSecret = "****";
            });

            app.UseGoogleAuthentication(options =>
            {
                options.ClientId = "*****";
                options.ClientSecret = "***";
            });



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

                routes.MapRoute(
                    name: "view",
                    template: "{customName}/{id}",
                    defaults: new { controller = "View", action = "Index" });

            });

        }

person chemitaxis    schedule 07.04.2016    source источник
comment
Используете ли вы кеш Azure Redis?   -  person juvchan    schedule 07.04.2016
comment
Да, я использую кеш Redis   -  person chemitaxis    schedule 07.04.2016


Ответы (1)


Сессия не связана с аутентификацией, вы пытаетесь решить ее неправильным способом.

Все билеты проверки подлинности форм и файлы cookie зашифрованы и подписаны с использованием уровня защиты данных. Проблема, с которой вы столкнулись, связана с тем, что ключи шифрования не сохраняются, а приложения изолированы друг от друга.

Чтобы решить эту проблему, вы должны поделиться обоими ключами шифрования и установить имя приложения в своем коде. Честно говоря, я бы рекомендовал вам этого не делать. Предварительная версия — это не действующий сервис, и вы не сможете пройти аутентификацию в обоих сразу.

Если вы чувствуете, что должны это сделать, вам нужно поделиться связкой ключей шифрования и установить фиксированное имя приложения. Вы можете делиться ключами через общую папку или хранить их в общем расположении, таком как SQL или хранилище Azure. Для этого вам придется написать собственный поставщик ключей, внедрив IXmlRepository. После того, как ваши ключи будут общими, вы можете установить фиксированный идентификатор приложения, используя SetApplicationName во время настройки защиты данных.

person blowdart    schedule 07.04.2016
comment
Спасибо за ваш ответ, но я не хочу делиться сеансом между средами. Моя проблема в том, что когда я делаю своп, пользователь теряет сеанс в производстве. - person chemitaxis; 07.04.2016
comment
В вашем вопросе упоминаются логины и необходимость повторного входа в систему. Так проблема в повторном входе? Или сессия? Или оба? - person blowdart; 07.04.2016
comment
Пользователю необходимо повторно войти в систему после замены - person chemitaxis; 07.04.2016
comment
Так что мой ответ правильный. Логины не сохраняются в сеансе. Вы должны поделиться ключами шифрования, чтобы логин на одном сервере можно было расшифровать на другом. - person blowdart; 07.04.2016
comment
Спасибо, есть ли у меня другой вариант? Хранение логинов в другом месте? Для меня это слишком плохой вариант... - person chemitaxis; 07.04.2016
comment
Нет. Логины всегда были файлами cookie, потому что это предотвращает уязвимости, связанные с перехватом сеанса. - person blowdart; 07.04.2016
comment
Еще раз спасибо. Могу ли я сохранить ключи шифрования в своем коде? - person chemitaxis; 07.04.2016
comment
Клавиши постоянно меняются. Я мог бы догадаться и установить действительно большой период вращения ключа, но это действительно очень плохая идея. - person blowdart; 07.04.2016