ASP.NET_SessionId + OWIN कुकीज़ ब्राउज़र पर नहीं भेजते हैं


145

मुझे ओविन कुकी प्रमाणीकरण का उपयोग करने में एक अजीब समस्या है।

जब मैं अपना IIS सर्वर प्रमाणीकरण शुरू करता हूं तो IE / Firefox और Chrome पर पूरी तरह से काम करता है।

मैंने विभिन्न प्लेटफार्मों पर प्रमाणीकरण और लॉगिंग के साथ कुछ परीक्षण करना शुरू किया और मैं एक अजीब त्रुटि के साथ आया हूं। छिटपुट रूप से ओविन फ्रेमवर्क / IIS ब्राउजरों को कोई भी कुकीज़ नहीं भेजता है। मैं एक उपयोगकर्ता नाम और पासवर्ड टाइप करूंगा जो कोड रन को सही करता है, लेकिन कोई भी कुकी ब्राउज़र को बिल्कुल भी डिलीवर नहीं होती है। यदि मैं सर्वर को फिर से शुरू करता हूं तो यह काम करना शुरू कर देता है तो कुछ बिंदु पर मैं लॉगिन करने की कोशिश करूंगा और फिर से कुकीज़ डिलीवर होना बंद हो जाएंगे। कोड पर कदम रखने से कुछ नहीं होता है और कोई त्रुटि नहीं होती है।

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

और मेरी लॉगिन प्रक्रिया के भीतर मेरे पास निम्नलिखित कोड हैं:

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

अद्यतन 1: ऐसा लगता है कि समस्या का एक कारण तब होता है जब मैं समस्याओं को शुरू करने के लिए आइटम जोड़ता हूं। कुछ सरल की तरह जोड़ना Session.Content["ABC"]= 123समस्या पैदा करता है।

मैं जो बना सकता हूं वह इस प्रकार है: 1) (क्रोम) जब मैं लॉगिन करता हूं तो मुझे ASP.NET_SessionId + मेरा प्रमाणीकरण कुकी मिलता है। 2) मैं एक पृष्ठ पर जाता हूं जो एक सत्र सेट करता है। कॉन्टेंट्स ... 3) एक नया ब्राउज़र (फ़ायरफ़ॉक्स) खोलें और लॉगिन का प्रयास करें और इसे ASP.NET_SessionId प्राप्त नहीं होता है और न ही इसे एक प्रमाणीकरण कुकी मिलती है 4) पहला ब्राउज़र ASP.NET_SessionId में यह काम करना जारी रखता है। जिस मिनट मैं इस कुकी को हटाता हूं, उसमें वही समस्या होती है, जो अन्य सभी ब्राउज़रों के साथ होती है, जो मैं आईपी एड्रेस (10.xxx) और लोकलहोस्ट पर काम कर रहा हूं।

अद्यतन 2:ASPNET_SessionId OWIN के साथ प्रमाणीकरण से पहले मेरे login_load पृष्ठ पर पहली बार फोर्स निर्माण ।

1) इससे पहले कि मैं ओविन के साथ प्रमाणित करूं मैं Session.ContentASP.NET_SessionId 2 शुरू करने के लिए अपने लॉगिन पृष्ठ पर एक यादृच्छिक मूल्य बनाता हूं ) फिर मैं प्रमाणित करता हूं और आगे के सत्र 3 करता हूं) अन्य ब्राउज़र अब काम करने लगते हैं

यह विचित्र है। मैं केवल यह निष्कर्ष निकाल सकता हूं कि एएसपी और ओविन के साथ यह सोचने के लिए कुछ है कि वे अलग-अलग डोमेन में हैं या ऐसा कुछ।

अपडेट 3 - दोनों के बीच अजीब व्यवहार।

पहचाने गए अतिरिक्त अजीब व्यवहार - ओवेन और एएसपी सत्र का समय अलग है। मैं जो देख रहा हूं, वह यह है कि मेरे ओविन सत्र मेरे एएसपी सत्रों की तुलना में लंबे समय तक जीवित रहे हैं। इसलिए जब लॉग इन करें: 1.) मेरे पास एक पका हुआ आधारित सेशन 2 सत्र है।) मैंने कुछ सत्र चर निर्धारित किए हैं

मेरा सत्र चर (2) उल्लू कुकी सत्र चर बलों को फिर से लॉगिन करने से पहले "मर" जाता है, जिससे मेरे पूरे आवेदन में अप्रत्याशित व्यवहार होता है। (व्यक्ति लॉग इन है, लेकिन वास्तव में लॉग इन नहीं है)

अपडेट 3 बी

कुछ खुदाई के बाद मैंने एक पृष्ठ पर कुछ टिप्पणियां देखीं जो कहती हैं कि "फ़ॉर्म" प्रमाणीकरण टाइमआउट और सत्र टाइमआउट को मिलान करने की आवश्यकता है। मैं आम तौर पर सोच रहा हूं कि दोनों सिंक में हैं लेकिन जो भी कारण है कि दोनों सिंक में नहीं हैं।

Workarounds का सारांश

1) हमेशा प्रमाणीकरण से पहले एक सत्र बनाएँ। जब आप एप्लिकेशन शुरू करते हैं तो मूल रूप से सत्र बनाएंSession["Workaround"] = 0;

2) [प्रायोगिक] यदि आप कुकीज़ को जारी रखते हैं तो सुनिश्चित करें कि आपका OWIN टाइमआउट / लंबाई आपके web.config (परीक्षण में) में आपके सेशनटाइम से अधिक लंबा है।


1
पुष्टि कर सकते हैं कि ActionResult लॉगिन और ActionResult ExternalLogin के लिए एक सत्र कॉल जोड़ना इस समस्या को ठीक करता है। मुझे यकीन है कि केवल एक की जरूरत है, लेकिन मेरे पास दोनों जगह हैं।
स्कॉट

धन्यवाद! ... एक्सटर्नलोगिन में सत्र जोड़ना मेरे लिए इसे ठीक कर दिया ... यह जादू जादू है ... मैं पहले से ही इस मुद्दे का शिकार करने के लिए 6 घंटे बर्बाद कर चुका
हूं

जवाबों:


159

मैंने एक ही समस्या का सामना किया है और इसका कारण OWIN ASP.NET होस्टिंग कार्यान्वयन को बताया है। मैं कहूंगा कि यह एक बग है।

कुछ पृष्ठभूमि

मेरे निष्कर्ष इन विधानसभा संस्करणों पर आधारित हैं:

  • Microsoft.Owin, संस्करण = 2.0.2.0, संस्कृति = तटस्थ, PublicKeyToken = 31bf3856ad364e35
  • Microsoft.Owin.Host.SystemWeb, संस्करण = 2.0.2.0, संस्कृति = तटस्थ, PublicKeyToken = 31bf3856ad364e35
  • System.Web, संस्करण = 4.0.0.0, संस्कृति = तटस्थ, PublicKeyToken = b03f5f7f11d50a3a

प्रतिक्रिया कूकीज़ ( Microsoft.Owin.ResponseCookieCollection ) के साथ काम करने के लिए OWIN इसका उपयोग करता है । यह कार्यान्वयन सीधे प्रतिक्रिया हेडर संग्रह को लपेटता है और तदनुसार सेट-कुकी हेडर को अपडेट करता है । OWIN ASP.NET होस्ट ( Microsoft.Owin.Host.SystemWeb ) केवल System.Web.HttpResponse को लपेटता है और यह हेडर संग्रह है। इसलिए जब OWIN के माध्यम से नई कुकी बनाई जाती है, तो प्रतिक्रिया सेट-कुकी हेडर को सीधे बदल दिया जाता है।

लेकिन ASP.NET भी प्रतिक्रिया कुकीज़ के साथ काम करने के लिए अपने स्वयं के अमूर्त का उपयोग करता है। यह हमें System.Web.HttpResponse.Cookies संपत्ति के रूप में उजागर करता है और सील वर्ग System.Web.HttpCookieCollection द्वारा कार्यान्वित किया जाता है । यह कार्यान्वयन सीधे सेट-कुकी हेडर को नहीं लपेटता है, लेकिन कुछ अनुकूलन और मुट्ठी भर आंतरिक सूचनाओं का उपयोग करके यह प्रकट करता है कि यह प्रतिक्रिया वस्तु में बदल गई है।

फिर जीवन भर अनुरोध में देर हो जाती है जहां HttpCookieCollection बदली हुई अवस्था का परीक्षण किया जाता है ( System.Web.HttpResponse.GenerateResponseHeadersForCookies () ) और कुकीज को सेट-कुकी हैडर में क्रमबद्ध किया जाता है । यदि यह संग्रह कुछ विशिष्ट स्थिति में है, तो पूरे सेट-कुकी शीर्षलेख को पहले संग्रह में संग्रहीत कुकीज़ से साफ़ और पुनः बनाया गया है।

ASP.NET सत्र कार्यान्वयन System.Web.HttpResponse.Cookies को ASP.NET_SessionId कुकी स्टोर करने के लिए संपत्ति का उपयोग करता है । इसके अलावा ASP.NET सत्र के राज्य मॉड्यूल में कुछ बुनियादी अनुकूलन है ( System.Web.SessionState.SessionStateModule ) जिसे s_sessionEverSet नाम की स्थैतिक संपत्ति के माध्यम से कार्यान्वित किया गया है जो कि काफी आत्म व्याख्यात्मक है। यदि आप कभी भी अपने आवेदन में सत्र राज्य के लिए कुछ स्टोर करते हैं, तो यह मॉड्यूल प्रत्येक अनुरोध के लिए थोड़ा और काम करेगा।


हमारी लॉगिन समस्या पर वापस

इन सभी टुकड़ों के साथ आपके परिदृश्यों को समझाया जा सकता है।

केस 1 - सत्र कभी निर्धारित नहीं किया गया था

System.Web.SessionState.SessionStateModule , s_sessionEverSet संपत्ति झूठी है। कोई सत्र आईडी सत्र राज्य मॉड्यूल और System.Web.HttpResponse.Cookies संग्रह राज्य द्वारा परिवर्तित के रूप में उत्पन्न नहीं होती है । इस मामले में OWIN कुकीज़ को ब्राउज़र और लॉगिन कार्यों के लिए सही तरीके से भेजा जाता है।

केस 2 - सत्र का उपयोग कहीं अनुप्रयोग में किया गया था, लेकिन उपयोगकर्ता द्वारा प्रमाणित करने का प्रयास करने से पहले नहीं

System.Web.SessionState.SessionStateModule , s_sessionEverSet गुण सत्य है। सत्र Id SessionStateModule द्वारा उत्पन्न की जाती है , ASP.NET_SessionId को System.Web.HttpResponse.Cookies संग्रह में जोड़ा जाता है, लेकिन बाद में इसे हटा दिया जाता है, क्योंकि उपयोगकर्ता का सत्र वास्तव में खाली है। इस स्थिति में System.Web.HttpResponse.Cookies संग्रह स्थिति को बदल दिया जाता है और कुकीज़ को हैडर मूल्य पर क्रमबद्ध करने से पहले सेट-कुकी शीर्षलेख को पहले साफ़ कर दिया जाता है।

इस मामले में OWIN प्रतिक्रिया कुकीज़ "खोई हुई" हैं और उपयोगकर्ता प्रमाणित नहीं है और लॉगिन पृष्ठ पर वापस भेज दिया गया है।

केस 3 - उपयोगकर्ता द्वारा प्रमाणित करने का प्रयास करने से पहले सत्र का उपयोग किया जाता है

System.Web.SessionState.SessionStateModule , s_sessionEverSet गुण सत्य है। सत्र आईडी SessionStateModule द्वारा बनाई गई है , ASP.NET_SessionId को System.Web.HttpResponse.Cookies में जोड़ा जाता है । में आंतरिक अनुकूलन के कारण System.Web.HttpCookieCollection और System.Web.HttpResponse.GenerateResponseHeadersForCookies () सेट कुकी शीर्ष लेख पहले नहीं मंजूरी दे दी है , लेकिन केवल अद्यतन किया गया।

इस मामले में OWIN प्रमाणीकरण कुकीज़ और ASP.NET_SessionId कुकी दोनों को प्रतिक्रिया और लॉगिन कार्यों में भेजा जाता है।


कुकीज़ के साथ अधिक सामान्य समस्या

जैसा कि आप देख सकते हैं कि समस्या अधिक सामान्य है और ASP.NET सत्र तक सीमित नहीं है। यदि आप Microsoft.win.Host.SystemWeb के माध्यम से OWIN की मेजबानी कर रहे हैं और आप / कुछ सीधे System.Web.HttpResponse.Cookies संग्रह का उपयोग कर रहे हैं तो आप जोखिम में हैं।

उदाहरण के लिए यह काम करता है और दोनों कुकीज़ को सही ढंग से ब्राउज़र पर भेजा जाता है ...

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

    return View();
}

लेकिन ऐसा नहीं होता है और ओविन्यूकी "खो गया" है ...

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

    return View();
}

दोनों ने VS2013, IISExpress और डिफ़ॉल्ट MVC प्रोजेक्ट टेम्पलेट से परीक्षण किया।


7
मैंने कुछ दिन बिताए हैं और हमारे परीक्षण वातावरण में इस मुद्दे को हल करने की कोशिश कर रहे हैं। मेरे द्वारा प्राप्त किया गया एकमात्र वर्कअराउंड वही है जो आपने सुझाया था (उपयोगकर्ता प्रमाणीकरण से पहले सत्र सेट करना)। मैंने इस मुद्दे को katanaproject ... katanaproject.codeplex.com/workitem/197 पर रिपोर्ट किया है , इसलिए शायद कोई वहां टिप्पणी करेगा।
टॉमस डोलेज़ल

11
यह एक बहुत ही गंभीर दोष है, खासकर जब से वे vs2013 के लिए टेम्पलेट को पैक करते हैं।
पिओटर स्टूलिंस्की

2
जो कोई भी इस बारे में और जांच करना चाहता है, मैंने उसके लिए github.com/Neilski/IdentityBugDemo
Neilski

1
नियंत्रक के उपयोग के कारण इस समस्या में चल रहा है। बेरोजगारी जो बैकिंग स्टोर के रूप में सत्र का उपयोग करती है। यदि ASP_NET.SessionId कुकी पिछले अनुरोध से मौजूद नहीं है, तो लॉगिन करने में असमर्थता को आसानी से पुन: उत्पन्न कर सकते हैं।
किंग्डैंगो

2
आखिरकार! यह कितना अजीब मुद्दा है। धन्यवाद। यह जवाब लिखे जाने के दो साल बाद भी यह एक मुद्दा है।
चंचल

43

@TomasDolezal द्वारा महान विश्लेषण के साथ शुरू, मैं दोनों Owin और System.Web स्रोत पर एक नज़र था।

समस्या यह है कि System.Web के पास कुकी जानकारी का अपना मास्टर स्रोत है और वह सेट-कुकी शीर्षलेख नहीं है। ओविन केवल सेट-कुकी हेडर के बारे में जानता है। वर्कअराउंड यह सुनिश्चित करने के लिए है कि ओविन द्वारा निर्धारित कोई भी कुकीज़ HttpContext.Current.Response.Cookiesसंग्रह में भी सेट की गई है ।

मैंने एक छोटा सा मिडलवेयर ( स्रोत , नगेट ) बनाया है जो वास्तव में ऐसा करता है, जिसका उद्देश्य कुकी मिडिलवेयर पंजीकरण के तुरंत बाद रखा जाना है।

app.UseKentorOwinCookieSaver();

app.UseCookieAuthentication(new CookieAuthenticationOptions());

1
इसे आजमाएंगे। Asp.net Identity 2.2.0-alp1 के बाद से मुझे न केवल लॉगिन पर बल्कि उपयोगकर्ता को लॉग आउट करने में भी समस्या होने लगी (उपयोगकर्ता लॉगआउट क्लिक पर लॉग आउट नहीं करेगा। आमतौर पर, जब मैं वेबसाइट को कुछ समय के लिए खुला छोड़ देता हूं तो बिना कुछ किए |) .. और लॉग इन समस्या के हल में उपयोगकर्ता के लॉग इन करने से ठीक पहले एक सत्र सेट करने के बाद, लेकिन लॉगआउट समस्या बनी रहती है .. आपके प्रयास के लिए धन्यवाद .. वैसे, क्या मुझे कुछ भी करना चाहिए, सिवाय स्थापना के पैकेज?
wooer

आपको इसे app.UseKentorCookieMiddlewareSaver();Startup.Auth.cs में सक्रिय करना होगा । इसे लॉगआउट कुकी क्लियरिंग भी संभालना चाहिए।
एंडर्स एबेल

बहुत बहुत धन्यवाद एंडर्स एबेल, लॉगिन और लॉगआउट दोनों अब ठीक काम करता है। लेकिन उपरोक्त टिप्पणी में कोड को बदलने की आवश्यकता है (क्योंकि मैंने इसका अनुसरण किया है :) बिना किसी सफलता के): app.UseKentorOwinCookieSaver()और शायद पैकेज के GitHub पृष्ठ के रूप में आप मूल उत्तर में शामिल हैं ।
वू डि डे

1
गलत डॉक्टर को नोटिस करने के लिए धन्यवाद। यह वास्तव में पहले से ही GitHub पेज पर तय हो गया है, लेकिन मैंने अपने उत्तर में अब भी यहां अपडेट किया है।
एंडर्स एबेल

@AndersAbel मैं इस github प्रोजेक्ट के लिए मीटअप साइनअप को जोड़ने की कोशिश कर रहा हूं: github.com/owin-middleware/OwinOAuthProviders ''। मैंने दूसरे दिन ही आसन को जोड़ा और कोई समस्या नहीं थी, लेकिन किसी कारण से, मीटअप के साथ, प्रतीक्षारत प्रमाणप्रमाण। दुर्भाग्य से, आपके NuGet पैकेज ने मेरी समस्या का समाधान नहीं किया। मैं सोच रहा था कि क्या आपके पास मेरे साथ समीक्षा करने के लिए कुछ समय होगा क्योंकि आप इस मुद्दे का बेहतर तरीके से निवारण कर सकते हैं और अपनी परियोजना को आगे बढ़ा सकते हैं।
एंथनी रफ़िनो

42

संक्षेप में, .NET कुकी प्रबंधक OWIN कुकी प्रबंधक पर जीत जाएगा और OWIN परत पर सेट कुकीज़ को अधिलेखित कर देगा । तय यह है कि यहां सिस्टम प्रोजेक्ट के रूप में प्रदान किए गए SystemWebCookieManager वर्ग का उपयोग किया जाए । आपको इस वर्ग या इसके समान उपयोग करने की आवश्यकता है, जो OWIN को .NET कुकी प्रबंधक का उपयोग करने के लिए मजबूर करेगा, ताकि कोई विसंगतियां न हों :

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

अपने एप्लिकेशन स्टार्टअप में, अपने OWIN निर्भरताएँ बनाते समय बस इसे असाइन करें:

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

इसी तरह का उत्तर यहां दिया गया है, लेकिन इसमें समस्या को हल करने के लिए आवश्यक सभी कोड-आधार शामिल नहीं हैं, इसलिए मुझे इसे यहां जोड़ने की आवश्यकता है क्योंकि कटाना परियोजना की बाहरी लिंक नीचे जा सकती है और इसे पूरी तरह से क्रोनिक होना चाहिए यहाँ भी एक समाधान के रूप में।


धन्यवाद, इसका काम मुझे, लेकिन मैं भी इस नियंत्रक फोन कॉल द्वारा सभी सत्र को साफ करता हूं। http: // cctetext.Session.RemoveAll (); in externallogincallback function
अदनान

ASP.NET वेबफॉर्म पर लागू होता है 4.6.1 ? मेरे वेबऐप का उपयोग करता हैASP.NET Webforms, OWIN, ADFS
Kiquenet

@Kiquenet क्या आपका वेब ऐप OWIN कुकीज़ का उपयोग करता है? तो ठीक।
अलेक्जेंड्रू

कोड में Startup.ConfigureAuthहमारे पास app.UseCookieAuthenticationऔर app.UseWsFederationAuthenticationअंत में app.UseStageMarker
Kiquenet

@Alexandru आप एक संपादन पर विचार कर सकते हैं, मेरी टीम ने इस बग को मारा और यह दुर्लभ और यादृच्छिक था, यह डीईवी और यूएटी वातावरण के माध्यम से हमसे छिपा हुआ था। आपके जवाब से यह उद्धरण हमारे लिए नहीं था: ".NET कुकी प्रबंधक हमेशा जीत जाएगा।" यह खोजना और ठीक करना आसान होगा, अगर OWIN कुकीज़ को हमेशा ओवरराइट किया जाता था, तो हमारे OIDC मिडलवेयर में से किसी ने भी इसे हमारे devstations से दूर नहीं किया होगा। लेकिन यादृच्छिकता का मतलब था कि बग ने इसे 2 दिनों के लिए उत्पादन करने के लिए सभी तरह से बना दिया था, इससे पहले कि यह हमें पैमाने पर मारता था (हमारे आंतरिक उपयोग AAD के माध्यम से प्रवेश नहीं कर सकता था)। यदि मैं आपके उत्तर से "हमेशा" शब्द हटाता हूँ तो मन?
yzorg

17

कटाना टीम ने टॉमस डोलजार को इस मुद्दे पर जवाब दिया , और वर्कअराउंड के बारे में दस्तावेज पोस्ट किए :

Workarounds दो श्रेणियों में आते हैं। एक तो System.Web को फिर से कॉन्फ़िगर करना है, इसलिए यह Response.Cookies संग्रह का उपयोग करने से बचता है और OWIN कुकीज़ को अधिलेखित करता है। अन्य दृष्टिकोण प्रभावित OWIN घटकों को फिर से कॉन्फ़िगर करना है ताकि वे सीधे System.Web के Response.Cookies संग्रह में कुकीज़ लिखें।

  • सुनिश्चित करें कि सत्र प्रमाणीकरण से पहले स्थापित किया गया है: System.Web और कटाना कुकीज़ के बीच संघर्ष अनुरोध के अनुसार है, इसलिए यह संभव है कि प्रमाणीकरण प्रवाह से पहले कुछ अनुरोध पर सत्र की स्थापना के लिए आवेदन संभव हो। उपयोगकर्ता के आने पर यह करना आसान होना चाहिए, लेकिन सत्र या ऑर्टिकल कुकीज़ समाप्त होने और / या ताज़ा करने की आवश्यकता होने पर बाद में गारंटी देना कठिन हो सकता है।
  • SessionStateModule को अक्षम करें - यदि आवेदन सत्र की जानकारी पर निर्भर नहीं कर रहा है, लेकिन सत्र मॉड्यूल अभी भी एक कुकी सेट कर रहा है जो उपरोक्त संघर्ष का कारण बनता है, तो आप सत्र राज्य मॉड्यूल को अक्षम करने पर विचार कर सकते हैं।
  • सीधे System.Web के कुकी संग्रह पर लिखने के लिए CookieAuthenticationMiddleware को फिर से कॉन्फ़िगर करें।
app.UseCookieAuthentication(new CookieAuthenticationOptions
                                {
                                    // ...
                                    CookieManager = new SystemWebCookieManager()
                                });

प्रलेखन से SystemWebCookieManager कार्यान्वयन देखें (लिंक ऊपर)

अधिक जानकारी यहाँ

संपादित करें

समस्या को हल करने के लिए हमने जो कदम उठाए हैं, उसके नीचे। 1. और 2. दोनों ने समस्या को अलग-अलग हल किया लेकिन हमने केवल मामले में दोनों को लागू करने का फैसला किया:

1. SystemWebCookieManager का उपयोग करें

2. सत्र चर सेट करें:

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

(साइड नोट: ऊपर की प्रारंभिक विधि फिक्स के लिए तार्किक स्थान है क्योंकि आधार। इंसुलेटाइज़ सेशन को उपलब्ध करता है। हालाँकि, बाद में भी फिक्स लागू किया जा सकता है क्योंकि OpenId में पहले एक अनाम अनुरोध है, फिर OpenId प्रदाता पर रीडायरेक्ट करें और फिर वापस। ऐप। समस्याएँ ऐप पर रीडायरेक्ट के बाद वापस आएंगी, जबकि फिक्स पहले अनाम अनुरोध के दौरान सत्र चर को पहले ही सेट कर देता है, इस प्रकार किसी भी रीडायरेक्ट के वापस आने से पहले समस्या को ठीक करता है)

संपादित करें २

कटाना परियोजना 2016-05-14 से कॉपी-पेस्ट :

इसे जोड़ो:

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

...और इस:

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

मुझे यह उत्तर अधिक सीधा और आसान लगता है कि इस मुद्दे को हल करना आसान है। धन्यवाद, - शायद मैंने भी अचानक बात की। इससे मेरी समस्या हल नहीं हुई।
जेसीएस

@ जेसीएस में इस मुद्दे को हल करने के लिए उठाए गए कदम शामिल थे। क्या आपको पता चला कि आपका मुद्दा संबंधित था?
थोमियस

मैं प्रमाणीकरण के लिए सत्र प्रबंधन के लिए वेब एपि 2 + ओविन मिडलवेयर + रेडिस कैश का उपयोग कर रहा हूं। मैंने SystemWebCookieManager का उपयोग करने की कोशिश की और यह उस समस्या को हल नहीं कर पाया जो मैं कर रहा था, जहाँ पर कुकीज़ को सेट नहीं किया जा रहा था। "UseKentorOwinCookieSaver" का उपयोग करके इसे हल किया है, लेकिन मैं एक अतिरिक्त बाहरी निर्भरता का शौकीन नहीं हूं ...
JCS

सत्र क्लियर करना मेरे लिए काम कर गया। किसी बाहरी निर्भरता की जरूरत नहीं। कॉल करने से पहले, इसे ControllerContext.HttpContext.Session.RemoveAll();अपनी ExternalLogin()कार्रवाई में रखें ChallengeResult()। मुझे नहीं पता कि यह सबसे अच्छा समाधान है, लेकिन यह सबसे सरल है।
एलिसन

1
@ chemitaxis यकीन है, बस ध्यान दें ?.(शून्य-सशर्त ऑपरेटर) केवल C # 6. में काम करता है
एलिसन

5

उत्तर पहले ही प्रदान किए जा चुके हैं, लेकिन उल्लिन 3.1.0 में, एक SystemWebChunkingCookieManager वर्ग है जिसका उपयोग किया जा सकता है।

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

क्या यह अभी भी 3.1.0 में एक समस्या है?
सायबरकोन्टे

1
हां, यह अभी भी मेरे लिए 3.1.0 में एक मुद्दा है और इस कुकी प्रबंधक की आवश्यकता है, क्योंकि डिफ़ॉल्ट अभी भी चनकिंगकाउज़र प्रबंधक है।
जोंमेयेर

कहाँ इस्तेमाल किया जा सकता है? और कैसे?
सिमोन_विवर

@jonmeyer धन्यवाद मुझे लगता है कि कल मैंने SystemCCM और CCM के बीच के अंतर को याद किया, इसलिए मैं निश्चित रूप से इसकी जाँच करूंगा
Simon_Weaver

ऊपर लाइन जोड़ने के बाद भी मेरे लिए काम नहीं कर रहा है। मैं 3.1.0 संस्करण का उपयोग कर रहा हूं। मुख्य रूप से मैं पहली बार लॉगिन करने में सक्षम हूं, लेकिन लॉगआउट के बाद इसकी मुझे लॉगिन करने की अनुमति नहीं है।
मितिन दीक्षित

3

यदि आप स्वयं OWIN मिडलवेयर में कुकीज़ सेट कर रहे हैं, तो उपयोग OnSendingHeadersकरने से समस्या का दौर लगता है।

उदाहरण के लिए, नीचे दिए गए कोड का उपयोग करके owinResponseCookie2सेट किया जाएगा, भले ही 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

मुझे विजुअल स्टूडियो 2017 और .net MVC 5.2.4 के साथ इसी तरह के मुद्दे का सामना करना पड़ा , Nuget Microsoft.Owin.Security.Google को नवीनतम संस्करण में अपडेट करना, जो वर्तमान में 4.0.1 है मेरे लिए काम करता है! आशा है कि यह किसी की मदद करता है!


1
इस पर मेरी बेकन को बचाया! एंड्रॉयड क्रोम के साथ एक समस्या थी विशेष रूप से यादृच्छिक पर प्रमाणीकरण खो रहा है। इस सूत्र में और कुछ नहीं काम किया। मैं वीएस २०१ ९ और एएसपी एमवीसी ५ का उपयोग कर रहा हूं
zfrank

2

सबसे तेज़ एक-पंक्ति कोड समाधान:

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

CreateIdentity विधि से पहले बस इस पंक्ति को जोड़ें:

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

1
आपने यह कोड कहां रखा है HttpContext.Current.Session["RunSession"] = "1";? में Globa.asax Session_Start ?
किवनीत

1
यह वास्तव में सबसे सरल और सबसे तेज़ उपलब्ध समाधान है, और जब तक उस समस्या का समाधान फ्रेमवर्क में शामिल नहीं किया जाएगा (पहले से ही घोषणा की गई है कि) - मैं, उदाहरण के लिए, एक-लाइनर पसंद करूंगा, बजाय निर्भरता के एक वर्ग + गुच्छा। । यह घोल IMHO को कम करके आंका गया है।
डेर जिंजर

मैंने इसे अपने AuthManager में IsAuthToken पद्धति के शीर्ष पर जोड़ा
अलेक्जेंडर

1

मेरे पास सेट-कुकी हेडर के समान लक्षण नहीं भेजे गए थे, लेकिन इनमें से किसी भी उत्तर ने मेरी मदद नहीं की। सब कुछ मेरे स्थानीय मशीन पर काम करता था लेकिन जब सेट-कुकी हेडर का उत्पादन करने के लिए तैनात किया जाता था तो वह कभी सेट नहीं होता था।

यह पता चला है कि यह CookieAuthenticationMiddlewareWebApi के साथ WebApi संपीड़न समर्थन के साथ एक कस्टम का उपयोग करने का एक संयोजन था

सौभाग्य से मैं अपने प्रोजेक्ट में ELMAH का उपयोग कर रहा था जिसने मुझे इस अपवाद को लॉग इन करने दिया:

System.Web.HttpException सर्वर HTTP हेडर भेजे जाने के बाद हेडर को संलग्न नहीं कर सकता है।

जो मुझे इस GitHub इश्यू की ओर ले गया

मूल रूप से, यदि आपके पास मेरा जैसा एक अजीब सेटअप है, तो आप अपने WebApi नियंत्रकों / विधियों के लिए संपीड़न अक्षम करना चाहेंगे जो कुकीज़ सेट करते हैं, या प्रयास करें OwinServerCompressionHandler

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.