ASP.NET_SessionId + OWIN Cookie tidak mengirim ke browser

145

Saya memiliki masalah aneh dengan menggunakan otentikasi cookie Owin.

Ketika saya memulai otentikasi server IIS saya berfungsi dengan baik di IE / Firefox dan Chrome.

Saya mulai melakukan beberapa pengujian dengan Otentikasi dan masuk pada platform yang berbeda dan saya menemukan kesalahan yang aneh. Kerangka kerja Owin / IIS secara sporadis tidak mengirim cookie apa pun ke browser. Saya akan mengetikkan nama pengguna dan kata sandi yang benar ketika kode berjalan tetapi tidak ada cookie yang dikirim ke browser sama sekali. Jika saya me-restart server itu mulai berfungsi maka di beberapa titik saya akan mencoba masuk dan lagi cookie berhenti terkirim. Melangkah kode tidak melakukan apa-apa dan tidak ada kesalahan.

 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);
                     }
                 }
               }
        });

Dan dalam prosedur login saya, saya memiliki kode berikut:

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);

Pembaruan 1: Tampaknya salah satu penyebab masalah adalah ketika saya menambahkan item ke sesi masalah dimulai. Menambahkan sesuatu yang sederhana seperti Session.Content["ABC"]= 123tampaknya menciptakan masalah.

Yang dapat saya lakukan adalah sebagai berikut: 1) (Chrome) Ketika saya masuk saya mendapatkan ASP.NET_SessionId + cookie otentikasi saya. 2) Saya pergi ke halaman yang menetapkan session.contents ... 3) Buka browser baru (Firefox) dan coba masuk dan tidak menerima ASP.NET_SessionId juga tidak mendapatkan Cookie Otentikasi 4) Sementara browser pertama memiliki ASP.NET_SessionId terus berfungsi. Begitu saya menghapus cookie ini, ia memiliki masalah yang sama dengan semua browser lain yang sedang saya kerjakan pada alamat ip (10.xxx) dan localhost.

Pembaruan 2: Memaksa pembuatan ASPNET_SessionIdpertama pada halaman login_load saya sebelum otentikasi dengan OWIN.

1) sebelum saya mengautentikasi dengan OWIN, saya membuat Session.Contentnilai acak pada halaman login saya untuk memulai ASP.NET_SessionId 2) kemudian saya mengautentikasi dan membuat sesi lebih lanjut 3) Browser lain tampaknya sekarang berfungsi

Ini aneh. Saya hanya dapat menyimpulkan bahwa ini ada hubungannya dengan ASP dan OWIN berpikir mereka berada di domain yang berbeda atau sesuatu seperti itu.

Perbarui 3 - Perilaku aneh antara keduanya.

Identifikasi perilaku aneh tambahan - Batas waktu sesi Owin dan ASP berbeda. Apa yang saya lihat adalah bahwa sesi Owin saya tetap hidup lebih lama dari sesi ASP saya melalui beberapa mekanisme. Jadi ketika masuk: 1.) Saya memiliki sesi auth berbasis cookie 2.) Saya menetapkan beberapa variabel sesi

Variabel sesi saya (2) "mati" sebelum variabel sesi cookie owin memaksa login ulang, yang menyebabkan perilaku tak terduga di seluruh aplikasi saya. (Orang masuk tetapi tidak benar-benar masuk)

Perbarui 3B

Setelah beberapa penggalian, saya melihat beberapa komentar pada halaman yang mengatakan batas waktu otentikasi "formulir" dan batas waktu sesi harus cocok. Saya pikir biasanya keduanya sinkron tetapi karena alasan apa pun keduanya tidak sinkron.

Ringkasan Penanganan Masalah

1) Selalu buat Sesi terlebih dahulu sebelum otentikasi. Pada dasarnya buat sesi ketika Anda memulai aplikasiSession["Workaround"] = 0;

2) [Eksperimental] jika Anda bertahan dengan cookie, pastikan batas waktu / panjang OWIN Anda lebih lama dari sessionTimeout Anda di web.config Anda (dalam pengujian)

Piotr Stulinski
sumber
1
Dapat mengonfirmasi bahwa menambahkan panggilan sesi ke ActionResult Login dan ActionResult ExternalLogin memperbaiki masalah ini. Saya yakin hanya satu yang dibutuhkan tetapi saya memiliki keduanya di tempat.
Scott
Terima kasih! ... Menambahkan Sesi di ExternalLogin memperbaikinya untuk saya ... ini adalah sihir voodoo ... saya sudah membuang waktu 6 jam untuk memburu masalah ini ..
xdev

Jawaban:

159

Saya telah mengalami masalah yang sama dan menelusuri penyebabnya untuk implementasi hosting OWIN ASP.NET. Saya akan mengatakan itu bug.

Beberapa latar belakang

Temuan saya didasarkan pada versi perakitan ini:

  • Microsoft.Owin, Versi = 2.0.2.0, Budaya = netral, PublicKeyToken = 31bf3856ad364e35
  • Microsoft.Owin.Host.SystemWeb, Versi = 2.0.2.0, Culture = netral, PublicKeyToken = 31bf3856ad364e35
  • System.Web, Versi = 4.0.0.0, Budaya = netral, PublicKeyToken = b03f5f7f11d50a3a

OWIN menggunakan abstraksinya sendiri untuk bekerja dengan Cookie tanggapan ( Microsoft.Owin.ResponseCookieCollection ). Implementasi ini secara langsung membungkus koleksi tajuk respons dan karenanya memperbarui tajuk Set-Cookie . OWIN ASP.NET host ( Microsoft.Owin.Host.SystemWeb ) baru saja membungkus System.Web.HttpResponse dan koleksi tajuknya . Jadi ketika cookie baru dibuat melalui OWIN, header Set-Cookie response diubah secara langsung.

Tetapi ASP.NET juga menggunakan abstraksi itu sendiri untuk bekerja dengan Cookie tanggapan. Ini dihadapkan kepada kami sebagai properti System.Web.HttpResponse.Cookies dan diimplementasikan oleh System.Web.HttpCookieCollection kelas tertutup . Implementasi ini tidak membungkus header Set-Cookie respons secara langsung tetapi menggunakan beberapa optimisasi dan beberapa notifikasi internal untuk mewujudkannya diubah menjadi objek respons.

Lalu ada titik keterlambatan dalam permintaan seumur hidup di mana HttpCookieCollection berubah status diuji ( System.Web.HttpResponse.GenerateResponseHeadersForCookies () ) dan cookie diserialisasi ke header Set-Cookie . Jika koleksi ini dalam keadaan tertentu, seluruh tajuk Set-Cookie pertama kali dihapus dan dibuat ulang dari cookie yang disimpan dalam koleksi.

Implementasi sesi ASP.NET menggunakan properti System.Web.HttpResponse.Cookies untuk menyimpan cookie ASP.NET_SessionId itu. Juga ada beberapa optimasi dasar dalam modul state sesi ASP.NET ( System.Web.SessionState.SessionStateModule ) diimplementasikan melalui properti statis bernama s_sessionEverSet yang cukup jelas. Jika Anda pernah menyimpan sesuatu ke keadaan sesi di aplikasi Anda, modul ini akan melakukan sedikit lebih banyak pekerjaan untuk setiap permintaan.


Kembali ke masalah login kita

Dengan semua bagian ini, skenario Anda dapat dijelaskan.

Kasus 1 - Sesi tidak pernah ditetapkan

Properti System.Web.SessionState.SessionStateModule , s_sessionEverSet salah. Tidak ada id sesi yang dihasilkan oleh modul status sesi dan status pengumpulan System.Web.HttpResponse.Cookies tidak terdeteksi saat diubah . Dalam hal ini, cookie OWIN dikirim dengan benar ke browser dan pekerjaan login.

Kasus 2 - Sesi digunakan di suatu tempat dalam aplikasi, tetapi tidak sebelum pengguna mencoba untuk mengotentikasi

Properti System.Web.SessionState.SessionStateModule , s_sessionEverSet benar. Session Id dihasilkan oleh SessionStateModule , ASP.NET_SessionId ditambahkan ke koleksi System.Web.HttpResponse.Cookies tetapi dihapus kemudian dalam permintaan seumur hidup karena sesi pengguna sebenarnya kosong. Dalam hal ini, kondisi pengumpulan System.Web.HttpResponse.Cookies terdeteksi sebagai diubah dan header Set-Cookie pertama kali dihapus sebelum cookie diserialisasi ke nilai header.

Dalam hal ini, cookie respons OWIN "hilang" dan pengguna tidak diautentikasi dan dialihkan kembali ke halaman masuk.

Kasus 3 - Sesi digunakan sebelum pengguna mencoba untuk mengotentikasi

Properti System.Web.SessionState.SessionStateModule , s_sessionEverSet benar. Id Session dihasilkan oleh SessionStateModule , ASP.NET_SessionId ditambahkan ke System.Web.HttpResponse.Cookies . Karena pengoptimalan internal di System.Web.HttpCookieCollection dan System.Web.HttpResponse.GenerateResponseHeadersForCookies () Header Set-Cookie TIDAK pertama kali dihapus tetapi hanya diperbarui.

Dalam hal ini, cookie autentikasi OWIN dan cookie ASP.NET_SessionId dikirim sebagai respons dan proses masuk.


Masalah yang lebih umum dengan cookie

Seperti yang Anda lihat masalahnya lebih umum dan tidak terbatas pada sesi ASP.NET. Jika Anda meng-hosting OWIN melalui Microsoft.Owin.Host.SystemWeb dan Anda / sesuatu langsung menggunakan System.Web.HttpResponse.Cookies koleksi Anda berisiko.

Misalnya ini berfungsi dan kedua cookie dikirim dengan benar ke browser ...

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

    return View();
}

Tapi ini tidak dan OwinCookie "hilang" ...

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

    return View();
}

Keduanya diuji dari VS2013, IISExpress dan template proyek MVC default.

Tomas Dolezal
sumber
7
Saya telah menghabiskan beberapa hari mencoba men-debug dan menyelesaikan masalah ini di lingkungan pengujian kami. Satu-satunya solusi yang saya temukan adalah sama seperti yang Anda sarankan (sesi pengaturan sebelum pengguna mengotentikasi). Saya telah melaporkan masalah ini ke katanaproject ... katanaproject.codeplex.com/workitem/197 , jadi mungkin seseorang akan berkomentar di sana.
Tomas Dolezal
11
Ini adalah kelemahan yang cukup serius, terutama karena mereka mengemas template untuk vs2013.
Piotr Stulinski
2
Bagi siapa pun yang ingin menyelidiki ini lebih lanjut, saya telah membuat proyek uji di github.com/Neilski/IdentityBugDemo
Neilski
1
Berlari ke masalah ini karena penggunaan Controller.TempData yang menggunakan Session sebagai backing store. Dapat dengan mudah mereproduksi ketidakmampuan untuk login jika cookie ASP_NET.SessionId tidak ada dari permintaan sebelumnya.
kingdango
2
Akhirnya! Masalah yang aneh ini. Terima kasih. Ini masih menjadi masalah selama dua tahun setelah jawaban ini ditulis.
Spivonious
43

Dimulai dengan analisis hebat oleh @TomasDolezal, saya telah melihat sumber Owin dan System.Web.

Masalahnya adalah bahwa System.Web memiliki sumber utama informasi cookie dan itu bukan header Set-Cookie. Owin hanya tahu tentang header Set-Cookie. Solusinya adalah memastikan bahwa cookie apa pun yang ditetapkan oleh Owin juga ditetapkan dalam HttpContext.Current.Response.Cookieskoleksi.

Saya telah membuat middleware kecil ( sumber , nuget ) yang melakukan hal itu, yang dimaksudkan untuk ditempatkan tepat di atas registrasi cookie middleware.

app.UseKentorOwinCookieSaver();

app.UseCookieAuthentication(new CookieAuthenticationOptions());
Anders Abel
sumber
1
Akan mencoba ini. Sejak setelah asp.net Identity 2.2.0-alpha1 saya mulai mengalami masalah tidak hanya pada saat login tetapi juga saat logout pengguna (pengguna tidak akan logout saat klik logout secara umum, dalam kasus ketika saya membiarkan situs web terbuka selama beberapa waktu). tanpa melakukan apa-apa |) .. Dan setelah mengatur sesi sebelum pengguna log in menyelesaikan masalah login tetapi masalah logout tetap ada .. Terima kasih atas upaya Anda .. Ngomong-ngomong, apakah ada yang harus saya lakukan kecuali untuk instalasi paket?
baik
Anda harus mengaktifkannya dengan app.UseKentorCookieMiddlewareSaver();di Startup.Auth.cs. Ini juga harus menangani pembersihan cookie logout.
Anders Abel
Terima kasih banyak Anders Abel, baik proses masuk dan keluar berfungsi dengan baik sekarang. Tetapi kode di komentar di atas perlu diubah (karena saya mengikutinya :) tanpa hasil) menjadi: app.UseKentorOwinCookieSaver()dan mungkin termasuk dalam Anda jawaban asli seperti pada halaman GitHub paket .
wooer
1
Terima kasih telah memperhatikan dokumen yang salah. Sebenarnya sudah diperbaiki pada halaman GitHub, tapi saya sudah memperbarui jawaban saya di sini juga sekarang.
Anders Abel
@AndersAbel Saya mencoba menambahkan pendaftaran Meetup untuk proyek github ini: github.com/owin-middleware/OwinOAuthProviders ''. Saya menambahkan Asana hanya beberapa hari yang lalu dan tidak memiliki masalah, tetapi untuk beberapa alasan, dengan Meetup, menunggu AuthenticationManager.GetExternalLoginInfoAsync () metode dalam Akun // ExternalLoginCallback mengembalikan nol. Sayangnya, paket NuGet Anda tidak menyelesaikan masalah saya. Saya bertanya-tanya apakah Anda punya waktu untuk meninjau dengan saya karena Anda mungkin dapat memecahkan masalah dengan lebih baik dan mendorong ke proyek Anda.
Anthony Ruffino
42

Singkatnya, manajer .NET cookie akan memenangkan manajer cookie OWIN dan menimpa cookie yang ditetapkan pada layer OWIN . Cara mengatasinya adalah dengan menggunakan kelas SystemWebCookieManager, yang disediakan sebagai solusi pada Proyek Katana di sini . Anda perlu menggunakan kelas ini atau yang serupa dengannya, yang akan memaksa OWIN untuk menggunakan .NET cookie manager sehingga tidak ada inkonsistensi :

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),
            });
    }
}

Di startup aplikasi Anda, tetapkan saja ketika Anda membuat dependensi OWIN Anda:

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

Jawaban serupa telah diberikan di sini tetapi tidak mencakup semua basis kode yang diperlukan untuk menyelesaikan masalah, jadi saya melihat perlunya menambahkannya di sini karena tautan eksternal ke Proyek Katana mungkin turun dan ini harus sepenuhnya dicatat sebagai solusi di sini juga.

Alexandru
sumber
terima kasih, ini berfungsi untuk saya, tetapi saya juga menghapus semua sesi dengan memanggil ControllerContext.HttpContext.Session.RemoveAll () ini; dalam fungsi externallogincallback
adnan
Apakah berlaku untuk ASP.NET Webforms 4.6.1 ? Aplikasi webApp sayaASP.NET Webforms, OWIN, ADFS
Kiquenet
@Kiquenet Apakah aplikasi web Anda menggunakan cookie OWIN? Lalu ya.
Alexandru
Dalam kode yang Startup.ConfigureAuthkita miliki app.UseCookieAuthenticationdan app.UseWsFederationAuthenticationakhirnya app.UseStageMarker
Kiquenet
@Alexandru Anda mungkin mempertimbangkan untuk mengedit, tim saya menemukan bug ini dan jarang dan acak, ia bersembunyi dari kami melalui lingkungan DEV dan UAT. Kutipan dari jawaban Anda ini tidak berlaku untuk kami: ". Cookie manager akan selalu menang." Itu akan mudah ditemukan dan diperbaiki, jika cookie OWIN selalu ditimpa, tidak ada middleware OIDC kami yang akan berhasil keluar dari workstation dev kami. Tetapi keacakan berarti bug membuat semua cara untuk produksi selama 2 hari sebelum mencapai skala kami (setengah penggunaan internal kami tidak bisa masuk melalui AAD). Keberatan jika saya menghapus kata "selalu" dari jawaban Anda?
yzorg
17

Tim Katana menjawab masalah yang diangkat Tomas Dolezar, dan memposting dokumentasi tentang pemecahan masalah :

Penanganannya terbagi dalam dua kategori. Salah satunya adalah mengkonfigurasi ulang System.Web sehingga ia menghindari menggunakan koleksi Response.Cookies dan menimpa cookie OWIN. Pendekatan lain adalah mengkonfigurasi ulang komponen OWIN yang terkena dampak sehingga mereka menulis cookie langsung ke koleksi System.eb's Response.Cookies.

  • Pastikan sesi dibuat sebelum otentikasi: Konflik antara System.Web dan cookie Katana adalah per permintaan, sehingga dimungkinkan untuk aplikasi untuk membuat sesi pada beberapa permintaan sebelum aliran otentikasi. Ini harus mudah dilakukan ketika pengguna pertama kali datang, tetapi mungkin lebih sulit untuk menjamin nanti ketika sesi atau cookie auth berakhir dan / atau perlu di-refresh.
  • Nonaktifkan SessionStateModule - Jika aplikasi tidak mengandalkan informasi sesi, tetapi modul sesi masih mengatur cookie yang menyebabkan konflik di atas, maka Anda dapat mempertimbangkan menonaktifkan modul status sesi.
  • Mengkonfigurasi ulang CookieAuthenticationMiddleware untuk menulis langsung ke koleksi cookie System.Web.
app.UseCookieAuthentication(new CookieAuthenticationOptions
                                {
                                    // ...
                                    CookieManager = new SystemWebCookieManager()
                                });

Lihat implementasi SystemWebCookieManager dari dokumentasi (tautan di atas)

Informasi lebih lanjut di sini

Edit

Di bawah langkah-langkah yang kami ambil untuk menyelesaikan masalah. 1. dan 2. menyelesaikan masalah secara terpisah tetapi kami memutuskan untuk menerapkan keduanya hanya dalam kasus:

1. Gunakan SystemWebCookieManager

2. Setel variabel sesi:

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;
}

(catatan: metode Inisialisasi di atas adalah tempat logis untuk perbaikan karena basis. Menginisialisasi membuat Sesi tersedia. Namun, perbaikan juga dapat diterapkan kemudian karena di OpenId pertama ada permintaan anonim, kemudian redirect ke penyedia OpenId dan kemudian kembali ke aplikasi. Masalahnya akan terjadi setelah pengalihan kembali ke aplikasi sementara perbaikan menetapkan variabel sesi sudah selama permintaan anonim pertama sehingga memperbaiki masalah sebelum terjadi pengalihan kembali bahkan terjadi)

Edit 2

Copy-paste dari proyek Katana 2016-05-14:

Tambahkan ini:

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

...dan ini:

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),
            });
    }
}
thomius
sumber
Saya menemukan jawaban ini jauh lebih mudah dan lebih mudah untuk memperbaiki masalah ini. Terima kasih, - Mungkin saya berbicara terlalu tiba-tiba. Ini tidak menyelesaikan masalah saya.
JCS
@ JSC Termasuk langkah-langkah yang kami ambil untuk menyelesaikan masalah. Apakah Anda mengetahui apakah masalah Anda terkait?
thomius
Saya menggunakan Web Api 2 + Owin middleware + redis cache untuk manajemen sesi untuk otentikasi. Saya mencoba menggunakan SystemWebCookieManager dan itu tidak memecahkan masalah yang saya alami di mana cookie auth tidak diatur. Menggunakan "UseKentorOwinCookieSaver" menyelesaikannya, tetapi saya tidak terlalu menyukai ketergantungan eksternal ekstra ...
JCS
Membersihkan sesi berhasil untuk saya. Tidak diperlukan ketergantungan eksternal. Letakkan ini ControllerContext.HttpContext.Session.RemoveAll();dalam ExternalLogin()tindakan Anda , sebelum menelepon ChallengeResult(). Saya tidak tahu apakah itu solusi terbaik, tetapi ini adalah yang paling sederhana.
Alisson
1
@chemitaxis yakin, perhatikan saja ?.(operator null-kondisional) hanya berfungsi di C # 6.
Alisson
5

Jawaban sudah disediakan, tetapi di owin 3.1.0, ada kelas SystemWebChunkingCookieManager yang dapat digunakan.

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()
    ...
});
Jononeyer
sumber
Apakah ini masih merupakan masalah di 3.1.0?
cyberconte
1
Ya, ini masih merupakan masalah dalam 3.1.0 untuk saya dan diperlukan pengelola cookie ini, karena yang default masih ChunkingCookieManager.
jonmeyer
bisa digunakan dimana? dan bagaimana?
Simon_Weaver
@jonmeyer terima kasih. Saya pikir kemarin saya melewatkan perbedaan antara SystemCCM dan CCM jadi saya pasti akan memeriksanya
Simon_Weaver
bahkan setelah menambahkan baris di atas tidak berfungsi untuk saya. saya menggunakan versi 3.1.0. Terutama saya bisa masuk pertama kali tetapi setelah keluar tidak memungkinkan saya untuk masuk.
Mitin Dixit
3

Jika Anda mengatur cookie di middleware OWIN sendiri, kemudian menggunakan OnSendingHeaderstampaknya untuk menyelesaikan masalah.

Misalnya, menggunakan kode di bawah owinResponseCookie2ini akan ditetapkan, meskipun owinResponseCookie1tidak:

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");
}
Appetere
sumber
3

Saya menghadapi Masalah Sejenis dengan Visual Studio 2017 dan .net MVC 5.2.4 , Memperbarui Nuget Microsoft.Owin.Security.Google ke versi terbaru yang saat ini 4.0.1 bekerja untuk saya! Semoga ini Membantu seseorang!

Ikram Shah
sumber
1
Disimpan bacon saya yang satu ini! Sedang mengalami masalah dengan Android Chrome khusus kehilangan otentikasi secara acak. Tidak ada yang lain di utas ini yang berfungsi. Saya menggunakan VS2019 dan ASP MVC 5.
zfrank
2

Solusi kode satu baris tercepat:

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

Cukup tambahkan baris ini sebelum metode CreateIdentity:

HttpContext.Current.Session["RunSession"] = "1";
var userIdentity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
_authenticationManager.SignIn(new AuthenticationProperties { IsPersistent = rememberLogin }, userIdentity);
Alexander Trofimov
sumber
1
Di mana Anda meletakkan kode ini HttpContext.Current.Session["RunSession"] = "1";? di Globa.asax Session_Start ?
Kiquenet
1
Ini sebenarnya adalah solusi paling sederhana dan tercepat, dan sampai solusi dari masalah itu tidak akan dimasukkan dalam Kerangka (sudah diumumkan akan) - Saya, misalnya, akan lebih suka satu-liner, daripada kelas + banyak dependensi . Solusi ini diremehkan IMHO.
Der Zinger
Saya menambahkannya di AuthManager saya di bagian atas metode IssueAuthToken
Alexander Trofimov
1

Saya memiliki gejala yang sama dengan tajuk Set-Cookie yang tidak dikirim tetapi tidak ada jawaban yang membantu saya. Semuanya bekerja pada mesin lokal saya tetapi ketika digunakan untuk produksi header cookie tidak akan pernah bisa ditetapkan.

Ternyata itu kombinasi menggunakan kustom CookieAuthenticationMiddlewaredengan WebApi bersama dengan dukungan kompresi WebApi

Untungnya saya menggunakan ELMAH dalam proyek saya yang memungkinkan saya untuk pengecualian ini dicatat:

Server System.Web.HttpException tidak dapat menambahkan header setelah header HTTP telah dikirim.

Yang membawa saya ke Masalah GitHub ini

Pada dasarnya, jika Anda memiliki pengaturan aneh seperti milik saya, Anda ingin menonaktifkan kompresi untuk pengontrol / metode WebApi Anda yang mengatur cookie, atau coba OwinServerCompressionHandler.

Hugh Jeffner
sumber