ASP.NET_SessionId + OWIN Çerezleri tarayıcıya gönderilmiyor


153

Owin tanımlama bilgisi kimlik doğrulamasını kullanırken tuhaf bir sorun yaşıyorum.

IIS sunucu kimlik doğrulamamı başlattığımda, IE / Firefox ve Chrome'da mükemmel şekilde çalışıyor.

Kimlik Doğrulama ile bazı testler yapmaya ve farklı platformlarda oturum açmaya başladım ve garip bir hata ile karşılaştım. Zaman zaman Owin çerçevesi / IIS tarayıcılara herhangi bir çerez göndermez. Kodun çalıştığı doğru olan ancak tarayıcıya hiçbir çerez gönderilmeyen bir kullanıcı adı ve şifre yazacağım. Sunucuyu yeniden başlatırsam çalışmaya başlar ve bir noktada oturum açmayı deneyeceğim ve çerezlerin teslim edilmesini durduracağım. Kodun üzerinden geçmek hiçbir şey yapmaz ve hata atmaz.

 app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationMode = AuthenticationMode.Active,
            CookieHttpOnly = true,
            AuthenticationType = "ABC",
            LoginPath = new PathString("/Account/Login"),
            CookiePath = "/",
            CookieName = "ABC",
            Provider = new CookieAuthenticationProvider
               {
                  OnApplyRedirect = ctx =>
                  {
                     if (!IsAjaxRequest(ctx.Request))
                     {
                        ctx.Response.Redirect(ctx.RedirectUri);
                     }
                 }
               }
        });

Ve oturum açma prosedürümde aşağıdaki koda sahibim:

IAuthenticationManager authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
                            authenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

var authentication = HttpContext.Current.GetOwinContext().Authentication;
var identity = new ClaimsIdentity("ABC");
identity.AddClaim(new Claim(ClaimTypes.Name, user.Username));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.User_ID.ToString()));
identity.AddClaim(new Claim(ClaimTypes.Role, role.myRole.ToString()));
    authentication.AuthenticationResponseGrant =
        new AuthenticationResponseGrant(identity, new AuthenticationProperties()
                                                   {
                                                       IsPersistent = isPersistent
                                                   });

authenticationManager.SignIn(new AuthenticationProperties() {IsPersistent = isPersistent}, identity);

Güncelleme 1: Sorunun nedenlerinden biri, oturuma öğeler eklediğimde sorunların başlaması gibi görünüyor. Gibi basit bir şey eklemek Session.Content["ABC"]= 123sorunu yaratıyor gibi görünüyor.

Yapabileceklerim aşağıdaki gibidir: 1) (Chrome) Giriş yaptığımda ASP.NET_SessionId + kimlik doğrulama çerezimi alıyorum. 2) Bir session.contents ayarlayan bir sayfaya gidiyorum ... 3) Yeni bir tarayıcı açın (Firefox) ve oturum açmayı deneyin ve bir ASP.NET_SessionId almıyor veya bir Kimlik Doğrulama Çerezi almıyor 4) İlk tarayıcıda ASP.NET_SessionId'ye sahiptir ve çalışmaya devam eder. Bu çerezi kaldırdığım dakika, ip adresi (10.xxx) ve localhost üzerinde çalıştığım diğer tüm tarayıcılarla aynı sorunu yaşıyor.

Güncelleme 2:ASPNET_SessionId OWIN ile kimlik doğrulamasından önce login_load sayfamda ilk oluşturulmasını zorunlu kılın.

1) OWIN ile kimlik doğrulamadan önce Session.ContentASP.NET_SessionId'yi başlatmak için oturum açma sayfamda rastgele bir değer oluşturuyorum 2) sonra kimlik doğrulaması yapıp başka oturumlar yapıyorum 3) Diğer tarayıcılar artık çalışıyor gibi görünüyor

Bu tuhaf. Sadece bunun ASP ve OWIN'in farklı alanlarda olduklarını veya buna benzer bir şey olduğunu düşünmeleriyle bir ilgisi olduğu sonucuna varabilirim.

Güncelleme 3 - İkisi arasında garip davranış.

Ek garip davranış tanımlandı - Owin ve ASP oturumunun zaman aşımı farklı. Gördüğüm şey, Owin oturumlarımın bazı mekanizmalar aracılığıyla ASP oturumlarımdan daha uzun süre canlı kaldığı. Yani oturum açarken: 1.) Cookied tabanlı bir kimlik doğrulama oturumum var 2.) Birkaç oturum değişkeni belirledim

Oturum değişkenlerim (2), owin tanımlama bilgisi oturum değişkeninden önce "ölüyor", yeniden oturum açmaya zorluyor, bu da tüm uygulamamda beklenmeyen davranışlara neden oluyor. (Kişi giriş yaptı ancak gerçekte giriş yapmadı)

3B Güncellemesi

Biraz araştırma yaptıktan sonra, bir sayfada "formlar" kimlik doğrulama zaman aşımının ve oturum zaman aşımının eşleşmesi gerektiğini söyleyen bazı yorumlar gördüm. Normalde ikisinin senkronize olduğunu düşünüyorum ama her ne sebeple olursa olsun ikisi senkronize değil.

Geçici Çözümlerin Özeti

1) Her zaman kimlik doğrulamasından önce bir Oturum oluşturun. Uygulamayı başlattığınızda temel olarak oturum oluşturunSession["Workaround"] = 0;

2) [Deneysel] Çerezleri devam ettirirseniz, OWIN zaman aşımınızın / uzunluğunuzun web.config'inizdeki (test sırasında) sessionTimeout'tan daha uzun olduğundan emin olun


1
ActionResult Login ve ActionResult ExternalLogin'e bir oturum çağrısı eklemenin bu sorunu çözdüğünü doğrulayabilir. Eminim sadece birine ihtiyaç vardır ama ikisine de sahibim.
Scott

Teşekkürler! ... ExternalLogin'e Oturum Eklemek benim için düzeltildi ... bu voodoo büyüsü ... Bu sorunu
çözmek

Yanıtlar:


163

Aynı sorunla karşılaştım ve nedenini OWIN ASP.NET barındırma uygulamasına kadar izledim. Bunun bir hata olduğunu söyleyebilirim.

Biraz geçmiş

Bulgularım şu montaj versiyonlarına dayanıyor:

  • Microsoft.Owin, Sürüm = 2.0.2.0, Kültür = tarafsız, PublicKeyToken = 31bf3856ad364e35
  • Microsoft.Owin.Host.SystemWeb, Sürüm = 2.0.2.0, Kültür = tarafsız, PublicKeyToken = 31bf3856ad364e35
  • System.Web, Sürüm = 4.0.0.0, Kültür = nötr, PublicKeyToken = b03f5f7f11d50a3a

OWIN, yanıt Çerezleri ( Microsoft.Owin.ResponseCookieCollection ) ile çalışmak için kendi soyutlamasını kullanır . Bu uygulama, yanıt başlıkları koleksiyonunu doğrudan sarar ve buna göre Set-Cookie başlığını günceller . OWIN ASP.NET ana bilgisayarı ( Microsoft.Owin.Host.SystemWeb ) yalnızca System.Web.HttpResponse ve başlık koleksiyonunu sarar . Dolayısıyla OWIN aracılığıyla yeni bir çerez oluşturulduğunda, Set-Cookie yanıtı doğrudan değiştirilir.

Ancak ASP.NET, yanıt tanımlama bilgileriyle çalışmak için kendi soyutlamasını da kullanır. Bu bize System.Web.HttpResponse.Cookies özelliği olarak maruz bırakılır ve mühürlenmiş System.Web.HttpCookieCollection sınıfı tarafından uygulanır . Bu uygulama, yanıtı Set-Cookie başlığını doğrudan sarmaz, ancak değişen durumunu yanıt nesnesine göstermek için bazı optimizasyonlar ve birkaç dahili bildirim kullanır.

Daha sonra, HttpCookieCollection değiştirilen durumunun test edildiği ( System.Web.HttpResponse.GenerateResponseHeadersForCookies () ) ve tanımlama bilgilerinin Set-Cookie başlığına serileştirildiği istek yaşam süresinde geç bir nokta vardır . Bu koleksiyon belirli bir durumdaysa, Set-Cookie başlığının tamamı önce temizlenir ve koleksiyonda depolanan çerezlerden yeniden oluşturulur.

ASP.NET oturum uygulaması, ASP.NET_SessionId tanımlama bilgisini depolamak için System.Web.HttpResponse.Cookies özelliğini kullanır . Ayrıca, kendi kendini açıklayan s_sessionEverSet adlı statik özellik aracılığıyla uygulanan ASP.NET oturum durumu modülünde ( System.Web.SessionState.SessionStateModule ) bazı temel optimizasyonlar vardır . Uygulamanızda oturum durumuna ilişkin bir şey saklarsanız, bu modül her istek için biraz daha fazla çalışma yapacaktır.


Giriş sorunumuza geri dönün

Tüm bu parçalarla senaryolarınız açıklanabilir.

Durum 1 - Oturum asla ayarlanmadı

System.Web.SessionState.SessionStateModule , s_sessionEverSet özelliği yanlış. Oturum durumu modülü tarafından hiçbir oturum kimliği üretilmez ve System.Web.HttpResponse.Cookies toplama durumu değiştirilmiş olarak algılanmaz . Bu durumda OWIN çerezleri tarayıcıya doğru bir şekilde gönderilir ve oturum açma çalışır.

Durum 2 - Oturum uygulamada bir yerde kullanıldı, ancak kullanıcı kimlik doğrulamaya çalışmadan önce kullanılmadı

System.Web.SessionState.SessionStateModule , s_sessionEverSet özelliği true. Oturum Kimlikleri SessionStateModule tarafından oluşturulur , ASP.NET_SessionId System.Web.HttpResponse.Cookies koleksiyonuna eklenir, ancak kullanıcının oturumu aslında boş olduğu için istek süresi içinde daha sonra kaldırılır. Bu durumda, System.Web.HttpResponse.Cookies toplama durumu değişmiş olarak algılanır ve tanımlama bilgileri başlık değerine serileştirilmeden önce Set-Cookie başlığı temizlenir.

Bu durumda, OWIN yanıt tanımlama bilgileri "kaybolur" ve kullanıcının kimliği doğrulanmaz ve tekrar oturum açma sayfasına yönlendirilir.

Durum 3 - Oturum, kullanıcı kimlik doğrulamaya çalışmadan önce kullanılıyor

System.Web.SessionState.SessionStateModule , s_sessionEverSet özelliği true. Oturum Kimlikleri SessionStateModule tarafından oluşturulur , ASP.NET_SessionId System.Web.HttpResponse.Cookies'e eklenir . Nedeniyle iç optimizasyon System.Web.HttpCookieCollection ve System.Web.HttpResponse.GenerateResponseHeadersForCookies () Set-Cookie başlığı ilk temizlenir DEĞİLDİR ancak güncellendi.

Bu durumda hem OWIN kimlik doğrulama tanımlama bilgileri hem de ASP.NET_SessionId tanımlama bilgisi yanıt olarak gönderilir ve oturum açma işlemi çalışır.


Çerezlerle ilgili daha genel sorun

Gördüğünüz gibi sorun daha geneldir ve ASP.NET oturumuyla sınırlı değildir. OWIN'i Microsoft.Owin.Host.SystemWeb aracılığıyla barındırıyorsanız ve siz / bir şey doğrudan System.Web.HttpResponse.Cookies koleksiyonunu kullanıyorsanız risk altındasınız demektir .

Örneğin bu çalışır ve her iki çerez de doğru bir şekilde tarayıcıya gönderilir ...

public ActionResult Index()
{
    HttpContext.GetOwinContext()
        .Response.Cookies.Append("OwinCookie", "SomeValue");
    HttpContext.Response.Cookies["ASPCookie"].Value = "SomeValue";

    return View();
}

Ama bu olmaz ve OwinCookie "kaybolur" ...

public ActionResult Index()
{
    HttpContext.GetOwinContext()
        .Response.Cookies.Append("OwinCookie", "SomeValue");
    HttpContext.Response.Cookies["ASPCookie"].Value = "SomeValue";
    HttpContext.Response.Cookies.Remove("ASPCookie");

    return View();
}

Her ikisi de VS2013, IISExpress ve varsayılan MVC proje şablonundan test edilmiştir.


8
Test ortamımızda bu sorunu gidermek ve çözmek için birkaç gün geçirdim. Bulduğum tek geçici çözüm önerdiğinizle aynı (kullanıcı kimlik doğrulamasından önce oturum ayarlama). Sorunu katanaproject ... katanaproject.codeplex.com/workitem/197 adresine rapor ettim , bu yüzden belki birisi orada yorum yapabilir.
Tomas Dolezal

13
Bu oldukça ciddi bir kusur, özellikle de vs2013 şablonunu owin paketledikleri için.
Piotr Stulinski

3
Bunu daha fazla araştırmak isteyen herkes için github.com/Neilski/IdentityBugDemo adresinde bir test projesi oluşturdum
Neilski

1
Destek deposu olarak Session kullanan Controller.TempData kullanımından dolayı bu problemle karşılaşılıyor. Önceki bir istekte bir ASP_NET.SessionId tanımlama bilgisi yoksa, oturum açamama durumunu kolayca yeniden oluşturabilir.
kingdango

2
En sonunda! Bu ne kadar tuhaf bir konu. Teşekkür ederim. Bu, bu yanıtın yazılmasının ardından iki yıldan fazla bir süredir devam eden bir sorundur.
Spivonious

48

Kısaca, .NET tanımlama bilgisi yöneticisi, OWIN tanımlama bilgisi yöneticisini kazanacak ve OWIN katmanında ayarlanan tanımlama bilgilerinin üzerine yazacaktır . Düzeltme, burada Katana Projesi'nde bir çözüm olarak sağlanan SystemWebCookieManager sınıfını kullanmaktır . Bu sınıfı veya ona benzer bir sınıfı kullanmanız gerekir; bu, OWIN'i .NET tanımlama bilgisi yöneticisini kullanmaya zorlar, böylece tutarsızlıklar olmaz :

public class SystemWebCookieManager : ICookieManager
{
    public string GetRequestCookie(IOwinContext context, string key)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
        var cookie = webContext.Request.Cookies[key];
        return cookie == null ? null : cookie.Value;
    }

    public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (options == null)
        {
            throw new ArgumentNullException("options");
        }

        var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);

        bool domainHasValue = !string.IsNullOrEmpty(options.Domain);
        bool pathHasValue = !string.IsNullOrEmpty(options.Path);
        bool expiresHasValue = options.Expires.HasValue;

        var cookie = new HttpCookie(key, value);
        if (domainHasValue)
        {
            cookie.Domain = options.Domain;
        }
        if (pathHasValue)
        {
            cookie.Path = options.Path;
        }
        if (expiresHasValue)
        {
            cookie.Expires = options.Expires.Value;
        }
        if (options.Secure)
        {
            cookie.Secure = true;
        }
        if (options.HttpOnly)
        {
            cookie.HttpOnly = true;
        }

        webContext.Response.AppendCookie(cookie);
    }

    public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (options == null)
        {
            throw new ArgumentNullException("options");
        }

        AppendResponseCookie(
            context,
            key,
            string.Empty,
            new CookieOptions
            {
                Path = options.Path,
                Domain = options.Domain,
                Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
            });
    }
}

Uygulama başlangıcınızda, OWIN bağımlılıklarınızı oluşturduğunuzda bunu atayın:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    ...
    CookieManager = new SystemWebCookieManager()
    ...
});

Burada benzer bir cevap sağlanmıştır, ancak sorunu çözmek için gereken tüm kod tabanını içermemektedir, bu yüzden buraya eklemem gerektiğini görüyorum çünkü Katana Projesi'nin harici bağlantısı düşebilir ve bu tamamen kronikleştirilmelidir. burada da bir çözüm olarak.


teşekkürler, benim işim, ama aynı zamanda bu ControllerContext.HttpContext.Session.RemoveAll () 'ı çağırarak tüm oturumu temizliyorum; in externallogincallback işlevi
adnan

ASP.NET Webforms 4.6.1 için geçerli midir? Benim web uygulamamın kullandığıASP.NET Webforms, OWIN, ADFS
Kiquenet

@Kiquenet Web uygulamanız OWIN çerezlerini kullanıyor mu? O zaman evet.
Alexandru

Kodunda Startup.ConfigureAuthElimizdeki app.UseCookieAuthenticationve app.UseWsFederationAuthenticationnihayet ve app.UseStageMarker
Kiquenet

@Alexandru Bir düzenleme düşünebilirsiniz, ekibim bu hatayı vurdu ve nadir ve rastgele oldu, DEV ve UAT ortamları aracılığıyla bizden saklandı. Cevabınızdan aldığınız bu alıntı bizim için geçerli değildi: ".NET çerez yöneticisi her zaman kazanacaktır." OWIN tanımlama bilgileri her zaman üzerine yazılsaydı, OIDC ara katman yazılımlarımızdan hiçbiri onu geliştirici iş istasyonlarımızdan kurtaramazdı. Ancak rastgelelik, hatanın bize ölçeğe ulaşmadan önce 2 gün boyunca üretime kadar ulaştığı anlamına geliyordu (dahili kullanımlarımızın yarısı AAD aracılığıyla giriş yapamadı). Cevabınızdan "her zaman" kelimesini çıkarabilir miyim?
yzorg

45

@TomasDolezal tarafından yapılan harika analizden başlayarak, hem Owin hem de System.Web kaynağına bir göz attım.

Sorun, System.Web'in kendi ana çerez bilgisi kaynağına sahip olmasıdır ve bu Set-Cookie başlığı değildir. Owin yalnızca Set-Cookie başlığını bilir. Çözüm, Owin tarafından ayarlanan tüm çerezlerin HttpContext.Current.Response.Cookieskoleksiyonda da ayarlandığından emin olmaktır .

Tam olarak bunu yapan, çerez ara yazılım kaydının hemen üstüne yerleştirilmesi amaçlanan küçük bir ara yazılım ( kaynak , nuget ) yaptım .

app.UseKentorOwinCookieSaver();

app.UseCookieAuthentication(new CookieAuthenticationOptions());

1
Bunu bir deneyecek. Asp.net Identity 2.2.0-alpha1'den sonra, yalnızca oturum açarken değil, aynı zamanda kullanıcının oturumunu kapatırken de sorun yaşamaya başladım (genellikle, web sitesini bir süre açık bırakmam durumunda, kullanıcı oturumu kapat düğmesine tıklamaz | genellikle hiçbir şey yapmadan |) .. Ve kullanıcı oturum açmadan hemen önce bir oturum ayarladıktan sonra oturum açma sorununu çözdü, ancak oturum kapatma sorunu devam ediyor .. Çabanız için teşekkürler .. Bu arada, kurulumu dışında yapmam gereken herhangi bir şey var mı? paket?
wooer

app.UseKentorCookieMiddlewareSaver();Startup.Auth.cs ile etkinleştirmeniz gerekir . Çıkış tanımlama bilgisi temizlemesini de ele almalıdır.
Anders Abel

Çok teşekkür ederim Anders Abel, hem giriş hem de çıkış artık iyi çalışıyor. Ancak yukarıdaki açıklamadaki kodun değiştirilmesi gerekiyor (çünkü onu takip ettim :) başarı olmadan): app.UseKentorOwinCookieSaver()ve belki de paketin GitHub sayfasında olduğu gibi orijinal cevabınıza dahil edilebilir .
wooer

1
Yanlış dokümanı fark ettiğiniz için teşekkürler. Aslında GitHub sayfasında zaten düzeltildi, ancak şimdi cevabımı burada da güncelledim.
Anders Abel

@AndersAbel Bu github projesi için Meetup kayıtlarını eklemeye çalışıyorum: github.com/owin-middleware/OwinOAuthProviders ''. Asana'yı geçen gün ekledim ve herhangi bir sorun yaşamadım, ancak bazı nedenlerden dolayı, Meetup ile, Account // ExternalLoginCallback'de bekleyen AuthenticationManager.GetExternalLoginInfoAsync () yöntemi boş döndürüyor. Maalesef NuGet paketiniz sorunumu çözmedi. Sorunu daha iyi giderebileceğiniz ve projenize aktarabileceğiniz için benimle gözden geçirmek için biraz zamanınız olup olmadığını merak ediyordum.
Anthony Ruffino

19

Katana ekibi, Tomas Dolezar'ın gündeme getirdiği soruna yanıt verdi ve geçici çözümler hakkında belgeler yayınladı :

Geçici çözümler iki kategoriye ayrılır. Birincisi, System.Web'i yeniden yapılandırmak, böylece Response.Cookies koleksiyonunu kullanmaktan ve OWIN tanımlama bilgilerinin üzerine yazmaktan kaçınmaktır. Diğer yaklaşım, etkilenen OWIN bileşenlerini yeniden yapılandırarak tanımlama bilgilerini doğrudan System.Web'in Response.Cookies koleksiyonuna yazmalarıdır.

  • Kimlik doğrulamadan önce oturumun kurulduğundan emin olun: System.Web ve Katana çerezleri arasındaki çakışma istek başınadır, bu nedenle uygulamanın kimlik doğrulama akışından önce bazı talepler üzerine oturumu oluşturması mümkün olabilir. Kullanıcı ilk geldiğinde bunu yapmak kolay olmalı, ancak daha sonra oturum veya kimlik doğrulama çerezlerinin süresi dolduğunda ve / veya yenilenmesi gerektiğinde bunu garanti etmek daha zor olabilir.
  • SessionStateModule'u Devre Dışı Bırakın - Uygulama oturum bilgisine güvenmiyorsa, ancak oturum modülü hala yukarıdaki çakışmaya neden olan bir tanımlama bilgisi ayarlıyorsa, oturum durumu modülünü devre dışı bırakmayı düşünebilirsiniz.
  • CookieAuthenticationMiddleware'i doğrudan System.Web'in tanımlama bilgisi koleksiyonuna yazmak için yeniden yapılandırın.
app.UseCookieAuthentication(new CookieAuthenticationOptions
                                {
                                    // ...
                                    CookieManager = new SystemWebCookieManager()
                                });

Belgelerden SystemWebCookieManager uygulamasına bakın (yukarıdaki bağlantı)

Daha fazla bilgi burada

Düzenle

Sorunu çözmek için attığımız adımların altında. Hem 1. hem de 2. sorunu ayrı ayrı çözdüler, ancak her iki durumda da uygulamaya karar verdik:

1. SystemWebCookieManager'ı kullanın

2. Oturum değişkenini ayarlayın:

protected override void Initialize(RequestContext requestContext)
{
    base.Initialize(requestContext);

    // See http://stackoverflow.com/questions/20737578/asp-net-sessionid-owin-cookies-do-not-send-to-browser/
    requestContext.HttpContext.Session["FixEternalRedirectLoop"] = 1;
}

(yan not: yukarıdaki Initialize yöntemi, düzeltme için mantıklı bir yerdir çünkü base.Initialize, Session'ı kullanılabilir kılar. Ancak, düzeltme daha sonra da uygulanabilir çünkü OpenId'de önce anonim bir istek vardır, ardından OpenId sağlayıcısına ve ardından geri yönlendirme Uygulamaya yönlendirilir. Sorunlar, uygulamaya geri yönlendirmeden sonra ortaya çıkarken, düzeltme, oturum değişkenini ilk anonim istek sırasında zaten ayarlar ve böylece herhangi bir yeniden yönlendirme gerçekleşmeden önce sorunu çözer)

Düzenle 2

2016-05-14 Katana projesinden kopyalayıp yapıştırın :

Bunu ekle:

app.UseCookieAuthentication(new CookieAuthenticationOptions
                                {
                                    // ...
                                    CookieManager = new SystemWebCookieManager()
                                });

...ve bu:

public class SystemWebCookieManager : ICookieManager
{
    public string GetRequestCookie(IOwinContext context, string key)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
        var cookie = webContext.Request.Cookies[key];
        return cookie == null ? null : cookie.Value;
    }

    public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (options == null)
        {
            throw new ArgumentNullException("options");
        }

        var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);

        bool domainHasValue = !string.IsNullOrEmpty(options.Domain);
        bool pathHasValue = !string.IsNullOrEmpty(options.Path);
        bool expiresHasValue = options.Expires.HasValue;

        var cookie = new HttpCookie(key, value);
        if (domainHasValue)
        {
            cookie.Domain = options.Domain;
        }
        if (pathHasValue)
        {
            cookie.Path = options.Path;
        }
        if (expiresHasValue)
        {
            cookie.Expires = options.Expires.Value;
        }
        if (options.Secure)
        {
            cookie.Secure = true;
        }
        if (options.HttpOnly)
        {
            cookie.HttpOnly = true;
        }

        webContext.Response.AppendCookie(cookie);
    }

    public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (options == null)
        {
            throw new ArgumentNullException("options");
        }

        AppendResponseCookie(
            context,
            key,
            string.Empty,
            new CookieOptions
            {
                Path = options.Path,
                Domain = options.Domain,
                Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
            });
    }
}

Bu cevabı çok daha basit buluyorum ve sorunu düzeltmek daha kolay. Teşekkürler, - Belki aniden konuştum. Bu benim sorunumu çözmedi.
JCS

@JCS Sorunu çözmek için attığımız adımları içeriyor. Sorununuzun ilgili olup olmadığını öğrendiniz mi?
thomius

Kimlik doğrulama için oturum yönetimi için Web Api 2 + Owin ara yazılımı + redis önbelleğini kullanıyorum. SystemWebCookieManager'ı kullanmaya çalıştım ve bu, kimlik doğrulama çerezlerinin ayarlanmadığı yerde yaşadığım sorunu çözmedi. "UseKentorOwinCookieSaver" kullanmak sorunu çözdü, ancak ekstra bir harici bağımlılıktan pek hoşlanmıyorum ...
JCS

Oturumu temizlemek benim için çalıştı. Dış bağımlılık gerekmez. Aramadan önce bunu eyleminize ControllerContext.HttpContext.Session.RemoveAll();ekleyin . Bunun en iyi çözüm olup olmadığını bilmiyorum ama en basit olanı. ExternalLogin()ChallengeResult()
Alisson

1
Emin @chemitaxis, sadece not almak ?.sadece C # 6. çalışır (boş-koşullu operatörü)
Alisson

8

Cevaplar zaten sağlanmıştır, ancak owin 3.1.0'da kullanılabilecek bir SystemWebChunkingCookieManager sınıfı vardır.

https://github.com/aspnet/AspNetKatana/blob/dev/src/Microsoft.Owin.Host.SystemWeb/SystemWebChunkingCookieManager.cs

https://raw.githubusercontent.com/aspnet/AspNetKatana/c33569969e79afd9fb4ec2d6bdff877e376821b2/src/Microsoft.Owin.Host.SystemWeb/SystemWebChunkingCookieManager.cs

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    ...
    CookieManager = new SystemWebChunkingCookieManager()
    ...
});

Bu hala 3.1.0'da bir sorun mu?
cyberconte

1
Evet, bu benim için hala 3.1.0'da bir sorundur ve varsayılan olan hala ChunkingCookieManager olduğundan, bu çerez yöneticisine ihtiyaç duymaktadır.
jonmeyer

nerede kullanılabilir? ve nasıl?
Simon_Weaver

@jonmeyer teşekkürler. Sanırım dün SystemCCM ve CCM arasındaki ayrımı kaçırdım, bu yüzden bunu kesinlikle kontrol edeceğim
Simon_Weaver

Üst satıra ekledikten sonra bile benim için çalışmıyor. 3.1.0 sürümünü kullanıyorum. Esasen ilk kez giriş yapabiliyorum, ancak çıkış yaptıktan sonra giriş yapmama izin vermiyor.
Mitin Dixit

3

OWIN ara yazılımında çerezleri kendiniz ayarlıyorsanız, o zaman kullanmak OnSendingHeaderssorunu çözüyor gibi görünüyor.

Örneğin, aşağıdaki kodun kullanılması owinResponseCookie2, öyle olmasa bile ayarlanacaktır owinResponseCookie1:

private void SetCookies()
{
    var owinContext = HttpContext.GetOwinContext();
    var owinResponse = owinContext.Response;

    owinResponse.Cookies.Append("owinResponseCookie1", "value1");

    owinResponse.OnSendingHeaders(state =>
    {
        owinResponse.Cookies.Append("owinResponseCookie2", "value2");
    },
    null);

    var httpResponse = HttpContext.Response;
    httpResponse.Cookies.Remove("httpResponseCookie1");
}

3

Visual Studio 2017 ve .net MVC 5.2.4 ile Benzer Sorunla karşılaştım, Nuget Microsoft.Owin.Security.Google'ı şu anda 4.0.1 olan en son sürüme güncelleyerek benim için çalıştı! Umarım bu birine yardımcı olur!


1
Pastırmamı bunda kurtardım! Android Chrome ile özellikle rasgele kimlik doğrulamasını kaybetme sorunu yaşıyordu. Bu ileti dizisindeki başka hiçbir şey işe yaramadı. VS2019 ve ASP MVC 5 kullanıyorum.
zfrank

2

En hızlı tek satırlık kod çözümü:

HttpContext.Current.Session["RunSession"] = "1";

CreateIdentity yönteminden önce bu satırı eklemeniz yeterlidir:

HttpContext.Current.Session["RunSession"] = "1";
var userIdentity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
_authenticationManager.SignIn(new AuthenticationProperties { IsPersistent = rememberLogin }, userIdentity);

2
Bu kodu nereye koydunuz HttpContext.Current.Session["RunSession"] = "1";? içinde Globa.asax Session_Start ?
Kiquenet

1
Aslında mevcut en basit ve en hızlı çözümdür ve bu sorunun çözümü Çerçeveye dahil edilmeyene kadar (zaten olacağını duyurmuştu) - örneğin, bir sınıf + bir grup bağımlılık yerine tek satırlı olmayı tercih ederim . Bu çözüm IMHO'nun hafife alınmaktadır.
Der Zinger

Bunu AuthManager'ıma IssueAuthToken yönteminin en üstüne ekledim
Alexander Trofimov

1

Set-Cookie başlığının aynı belirtisi gönderilmedi ama bu yanıtların hiçbiri bana yardımcı olmadı. Her şey yerel makinemde çalıştı, ancak üretime dağıtıldığında set-cookie başlıkları asla ayarlanmayacaktı.

CookieAuthenticationMiddlewareWebApi ile özel bir kullanımın yanı sıra WebApi sıkıştırma desteğinin bir kombinasyonu olduğu ortaya çıktı.

Neyse ki projemde bu istisnanın günlüğe kaydedilmesine izin veren ELMAH kullanıyordum:

System.Web.HttpException Sunucusu, HTTP üstbilgileri gönderildikten sonra üstbilgi ekleyemez.

Beni bu GitHub Sorununa götüren

Temel olarak, benimki gibi garip bir kurulumunuz varsa, WebApi denetleyicileriniz / çerezleri ayarlayan yöntemler için sıkıştırmayı devre dışı bırakmak isteyeceksiniz veya OwinServerCompressionHandler.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.