سؤال

حطمت رأسي هذا قليلا طويل جدا.كيف يمكن منع المستخدم من تصفح صفحات الموقع بعد تسجيل الخروج باستخدام FormsAuthentication.سينوت?أنا أتوقع أن تفعل ذلك:

FormsAuthentication.SignOut();
Session.Abandon();
FormsAuthentication.RedirectToLoginPage();

لكنه لا.إذا كنت اكتب في عنوان URL مباشرة, لا يزال يمكنني استعراض الصفحة.أنا لم تستخدم لفة بنفسك الأمن في كل حين حتى لا ننسى لماذا هذا لا يعمل.

هل كانت مفيدة؟

المحلول

ويمكن للمستخدمين لا يزال تصفح موقع الويب الخاص بك لأنه لا يتم مسح الكوكيز عند استدعاء FormsAuthentication.SignOut() ومصادقة أنها على كل طلب جديد. في وثائق MS هو يقول ان الكعكة سوف يتم مسح ولكن لم يفعلوا ذلك، وعلة؟ لها بالضبط نفس الشيء مع Session.Abandon()، الكعكة لا يزال هناك.

ويجب تغيير التعليمات البرمجية لهذا:

FormsAuthentication.SignOut();
Session.Abandon();

// clear authentication cookie
HttpCookie cookie1 = new HttpCookie(FormsAuthentication.FormsCookieName, "");
cookie1.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(cookie1);

// clear session cookie (not necessary for your current problem but i would recommend you do it anyway)
SessionStateSection sessionStateSection = (SessionStateSection)WebConfigurationManager.GetSection("system.web/sessionState");
HttpCookie cookie2 = new HttpCookie(sessionStateSection.CookieName, "");
cookie2.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(cookie2);

FormsAuthentication.RedirectToLoginPage();

وHttpCookie في مساحة الاسم System.Web. MSDN المرجعي .

نصائح أخرى

ويبدو لي ان لم يكن لديك قسم ترخيص الملف web.config الخاص تعيين بشكل صحيح داخل. انظر أدناه للحصول على مثال.

<authentication mode="Forms">
  <forms name="MyCookie" loginUrl="Login.aspx" protection="All" timeout="90" slidingExpiration="true"></forms>
</authentication>
<authorization>
  <deny users="?" />
</authorization>

باستخدام اثنين من فوق التعيينات من قبل x64igor و فيل Haselden حل هذه:

1.x64igor أعطى مثالا على القيام الخروج:

  • تحتاج أولا إلى مسح ملف تعريف ارتباط المصادقة و الكوكيز عن طريق تمرير تعود فارغة ملفات تعريف الارتباط في الرد على الخروج.

    public ActionResult LogOff()
    {
        FormsAuthentication.SignOut();
        Session.Clear();  // This may not be needed -- but can't hurt
        Session.Abandon();
    
        // Clear authentication cookie
        HttpCookie rFormsCookie = new HttpCookie( FormsAuthentication.FormsCookieName, "" );
        rFormsCookie.Expires = DateTime.Now.AddYears( -1 );
        Response.Cookies.Add( rFormsCookie );
    
        // Clear session cookie 
        HttpCookie rSessionCookie = new HttpCookie( "ASP.NET_SessionId", "" );
        rSessionCookie.Expires = DateTime.Now.AddYears( -1 );
        Response.Cookies.Add( rSessionCookie );
    

2.فيل Haselden أعطى المثال أعلاه كيفية منع التخزين المؤقت بعد الخروج:

  • تحتاج إلى يبطل ذاكرة التخزين المؤقت من جانب العميل عن طريق الرد.

        // Invalidate the Cache on the Client Side
        Response.Cache.SetCacheability( HttpCacheability.NoCache );
        Response.Cache.SetNoStore();
    
        // Redirect to the Home Page (that should be intercepted and redirected to the Login Page first)
        return RedirectToAction( "Index", "Home" ); 
    }
    

والمفتاح هنا هو أنك تقول "لو كنت اكتب في URL مباشرة ...".

وافتراضيا تحت مصادقة النماذج المتصفح بتخزين الصفحات للمستخدم. لذلك، اختيار URL مباشرة من المتصفحات معالجة مربع القائمة المنسدلة، أو كتابتها في، قد تحصل على الصفحة من ذاكرة التخزين المؤقت للمتصفح، وأعود أبدا إلى خادم للتحقق التوثيق / ترخيص. الحل لذلك هو منع التخزين المؤقت من جانب العميل في الحدث Page_Load كل صفحة، أو في ONLOAD () من الصفحة قاعدة الخاص بك:

Response.Cache.SetCacheability(HttpCacheability.NoCache);

وربما ترغب ايضا في الدعوة:

Response.Cache.SetNoStore();

ولقد كافح مع هذا من قبل أيضا.

وهنا القياس على ما يبدو أن يحدث ... ويمكن للزائر الجديد، جو، ويأتي إلى الموقع وتسجل في عبر صفحة تسجيل الدخول باستخدام FormsAuthentication. ASP.NET يولد هوية جديدة لجو، ويعطيه الكعكة. ملف تعريف الارتباط هذا هو مثل مفتاح المنزل، وطالما جو يعود مع هذا المفتاح، وانه يمكن فتح القفل. يعطى كل زائر مفتاح جديد وقفل جديد لاستخدامه.

وعندما يتم استدعاء FormsAuthentication.SignOut()، والنظام يقول جو لتفقد المفتاح. عادة، وهذا يعمل، منذ جو لم يعد لديه المفتاح، وقال انه لا يمكن أن تحصل في.

ومع ذلك، إذا جو يأتي من أي وقت مضى إلى الوراء، و<م> لا يكون هذا المفتاح المفقود، هو السماح انه ظهر في!

ومن ما استطيع ان اقول، لا توجد وسيلة لإخبار ASP.NET لتغيير القفل على الباب!

والطريقة أستطيع العيش مع ذلك هو أن نتذكر اسم جو في متغير الدورة. عندما يسجل، وأنا التخلي عن الدورة ولذا فإنني لم يكن لديك اسمه بعد الآن. وفي وقت لاحق، للتحقق مما إذا سمح له في، وأنا ببساطة مقارنة Identity.Name له ما لديها الدورة الحالية، وإذا كانت لا تطابق، وقال انه ليس زائرا صالح.

وباختصار، على موقع على شبكة الإنترنت، لا تعتمد على User.Identity.IsAuthenticated دون التحقق أيضا متغيرات جلسة بك!

وهذا يعمل بالنسبة لي

public virtual ActionResult LogOff()
    {
        FormsAuthentication.SignOut();
        foreach (var cookie in Request.Cookies.AllKeys)
        {
            Request.Cookies.Remove(cookie);
        }
        foreach (var cookie in Response.Cookies.AllKeys)
        {
            Response.Cookies.Remove(cookie);
        }
        return RedirectToAction(MVC.Home.Index());
    }

وبعد الكثير من البحث في النهاية هذا عمل بالنسبة لي. وآمل أن يساعد.

public ActionResult LogOff()
{
    AuthenticationManager.SignOut();
    HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);
    return RedirectToAction("Index", "Home");
}

<li class="page-scroll">@Html.ActionLink("Log off", "LogOff", "Account")</li>

وهذا الرمز الذي شارك تبدو مثل ذلك يجب إزالة بشكل صحيح الرمز المميز مصادقة النماذج، ولذلك فمن الممكن أن المجلدات / الصفحات في السؤال ليست محمية في الواقع.

هل أكد أن الصفحات لا يمكن الوصول من قبل أن وقعت على تسجيل الدخول؟

ويمكنك نشر إعدادات الملف web.config ورمز الدخول الذي تستخدمه؟

ولقد تم كتابة فئة أساسية لكافة الصفحات بلدي وجئت إلى نفس القضية. كان لي التعليمات البرمجية كما يلي ولكن ذلك لم ينجح. عن طريق تتبع، تمرير التحكم من RedirectToLoginPage () بيان إلى السطر التالي دون أن تتم إعادة توجيهه.

if (_requiresAuthentication)
{
    if (!User.Identity.IsAuthenticated)
        FormsAuthentication.RedirectToLoginPage();

    // check authorization for restricted pages only
    if (_isRestrictedPage) AuthorizePageAndButtons();
}

ولقد وجدت أن هناك نوعان من الحلول. إما لتعديل FormsAuthentication.RedirectToLoginPage ()؛ أن تكون

if (!User.Identity.IsAuthenticated)
    Response.Redirect(FormsAuthentication.LoginUrl);

وأو لتعديل الملف web.config عن طريق إضافة

<authorization>
  <deny users="?" />
</authorization>

في الحالة الثانية، في حين تتبع ومراقبة لم تصل إلى الصفحة المطلوبة. تم توجيهها على الفور إلى رابط تسجيل الدخول قبل أن تصل إلى نقطة فاصل. وبالتالي، وتسجيل الخروج () طريقة ليست القضية، وطريقة إعادة توجيه هو واحد.

وآمل أن قد تساعد شخص

والتحيات

ولقد حاول بعض الاقتراحات هنا، وبينما كنت قادرا على استخدام زر المتصفح مرة أخرى، وعندما ينقر على اختيار القائمة و[تخويل] رمز لذلك [ActionResult] أرسل لي الحق في العودة إلى شاشة تسجيل الدخول.

وهنا هو قانون بلدي الخروج:

        FormsAuthentication.SignOut();
        Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
        Response.Cache.SetExpires(DateTime.Now.AddSeconds(-1));
        HttpCookie cookie = HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
        if (cookie != null)
        {
            cookie.Expires = DateTime.Now.AddDays(-1);
            Response.Cookies.Add(cookie);
        }

وعلى الرغم من أن وظيفة مرة أخرى على متصفح أخذني إلى الوراء وعرض القائمة المضمونة (أنا لا تزال تعمل على ذلك) أنا لم أكن قادرا على القيام بأي شيء أن تم تأمين في التطبيق.

ويساعد هذا الأمل

ولقد حاول معظم الإجابات في هذا الموضوع، لا حظ. انتهى هذا:

protected void btnLogout_Click(object sender, EventArgs e)
{
    FormsAuthentication.Initialize();
    var fat = new FormsAuthenticationTicket(1, "", DateTime.Now, DateTime.Now.AddMinutes(-30), false, string.Empty, FormsAuthentication.FormsCookiePath);
    Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(fat)));
    FormsAuthentication.RedirectToLoginPage();
}

وجدت هنا: http://forums.asp.net/t/1306526. ASPX / 1

تحليل هذا الجواب هو متطابقة من الناحية الفنية لKhosro.Pakmanesh. أنا نشرها لتوضيح كيف جوابه يختلف عن إجابات أخرى على هذا الموضوع، وفي هذه الحالة استخدام يمكن استخدامه.

في عام لمسح الدورة المستخدم، والقيام

HttpContext.Session.Abandon();
FormsAuthentication.SignOut();

وسيتم تسجيل بفعالية المستخدم. ولكن ، إذا كان في طلب نفسه تحتاج إلى التحقق Request.isAuthenticated (كما قد يحدث في كثير من الأحيان في تصفية التصريح، على سبيل المثال)، ثم سوف تجد أن

Request.isAuthenticated == true

وحتى _after فعلتم HttpContext.Session.Abandon() وFormsAuthentication.SignOut().

والشيء الوحيد الذي عمل كان يقوم به

AuthenticationManager.SignOut();
HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);

وهذا يضع Request.isAuthenticated = false على نحو فعال.

وهذا بدأ يحدث لي عندما كنت تعيين <م> المصادقة> نماذج> الخاصية Path في Web.config. إزالة هذا إصلاح المشكلة، وFormsAuthentication.SignOut(); بسيطة إزالتها مرة أخرى الكعكة.

ويمكن أن يكون ذلك تقوم بتسجيل الدخول في من فرعي واحد (sub1.domain.com) ومن ثم محاولة الخروج من نطاق فرعي مختلف (www.domain.com).

ولقد كان نفس المشكلة، حيث تسجيل الخروج () فشلت على ما يبدو لإزالة تذكرة صحيح. ولكن فقط في حالة معينة، حيث تسبب بعض المنطق الآخر إعادة التوجيه. بعد أن إزالة هذه التحويلة الثانية (حل محل ذلك مع رسالة خطأ)، وذهب بعيدا المشكلة.

ويجب أن يكون والمشكلة أن الصفحة إعادة توجيه في الوقت الخطأ، وبالتالي لا تسبب المصادقة.

وأواجه مشكلة مشابهة الآن وأعتقد أن المشكلة في حالتي فضلا عن الملصق الأصلي هو بسبب إعادة التوجيه. بشكل افتراضي Response.Redirect يسبب استثناء التي فقاعات فورا حتى يتم القبض عليه ويتم تنفيذ إعادة التوجيه على الفور، وأنا التخمين أن هذا منع جمع الكعكة المعدلة من أن تنتقل إلى العميل. إذا قمت بتعديل التعليمات البرمجية لاستخدام:

Response.Redirect("url", false);

وهذا يمنع الاستثناء ويبدو أن تسمح ملفات تعريف الارتباط ليتم إرسالها بشكل صحيح مرة أخرى إلى العميل.

ومجرد محاولة لارسال متغير جلسة عمل عند الضغط على تسجيل الدخول. وعلى صفحة الترحيب، أولا التحقق مما إذا كانت تلك الدورة فارغة مثل هذا في تحميل الصفحة أو في الحدث التهيئة:

if(Session["UserID"] == null || Session["UserID"] == "")
{
    Response.Redirect("Login.aspx");
}

وبالنسبة لي، يعمل النهج التالي. اعتقد انه اذا كان هناك أي خطأ بعد "FormsAuthentication.SignOut ()" البيان SingOut لا يعمل.

public ActionResult SignOut()
    {
        if (Request.IsAuthenticated)
        {
            FormsAuthentication.SignOut();

            return Redirect("~/");
        }
        return View();
     }

هل اختبار / رؤية هذا السلوك باستخدام IE؟ فمن الممكن أن IE يقضي تصل تلك الصفحات من ذاكرة التخزين المؤقت. ومن الصعب بمكان أن تحصل IE لطرد انها ذاكرة التخزين المؤقت، وذلك في مناسبات عديدة، حتى بعد تسجيل الخروج، وكتابة عنوان الموقع من إحدى الصفحات "المضمونة" سوف تظهر محتوى مؤقتا من قبل.

و(لقد رأيت هذا السلوك حتى عند تسجيل الدخول كمستخدم مختلف، وIE يظهر شريط "مرحبا" في الجزء العلوي من الصفحة الخاصة بك، مع اسم المستخدم المستخدم القديم. في أيامنا هذه، عادة إعادة تحميل وتحديث، ولكن اذا كان فاضحة، ويمكن أن تكون لا تزال قضية التخزين المؤقت).

والقيام Session.abandon () وتدمير الكعكة يعمل جيد جدا. أنا باستخدام mvc3 ويبدو أن المشكلة تحدث إذا ذهبت إلى صفحة المحمية، تسجيل الخروج، والذهاب عبر التاريخ متصفحك. ليس صفقة كبيرة ولكن لا يزال كيندا من مزعج.

ومحاولة للذهاب من خلال الروابط على التطبيق الويب الخاص بي يعمل بالطريقة الصحيحة بالرغم من ذلك.

وتعيين إلى عدم قيام التخزين المؤقت المتصفح قد تكون وسيلة للذهاب.

لMVC يعمل هذا بالنسبة لي:

        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();
            return Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name, true));
        }

كنت أريد أن أضيف بعض المعلومات التي تساعد في فهم المشكلة.مصادقة النماذج يسمح لتخزين بيانات المستخدم سواء في الكوكيز أو في سلسلة الاستعلام URL.طريقة موقعك يدعم يمكن تكوين في شبكة الإنترنت.ملف التكوين.

ووفقا لمايكروسوفت:

فإن آثارها الأسلوب يزيل الأشكال-تذكرة مصادقة المعلومات من الكعكة أو URL إذا CookiesSupported كاذبة.

في نفس الوقت ، يقولون:

واحدة من HttpCookieMode القيم التي تشير إلى ما إذا كان التطبيق هو تكوين بدون ملفات تعريف ارتباط مصادقة النماذج. على الافتراضي هو UseDeviceProfile.

وأخيرا فيما يتعلق UseDeviceProfile, يقولون:

إذا كان CookieMode يتم تعيين الخاصية إلى UseDeviceProfile ، CookiesSupported العقار سيعود صحيح إذا كان متصفح الطلب الحالي يدعم كل ملفات تعريف الارتباط وإعادة توجيه مع الكوكيز;وإلا CookiesSupported الملكية return false.

التفكيك كل هذا معا ، اعتمادا على متصفح المستخدم ، التكوين الافتراضي قد يؤدي CookiesSupported يجري صحيح, مما يعني سينوت الأسلوب لا واضح تذكرة من الكعكة.هذا يبدو غير بديهية و لا أعرف لماذا يعمل هذا الطريق-أتوقع آثارها في الواقع تسجيل خروج المستخدم تحت أي ظرف من الظروف.

طريقة واحدة لجعل سينوت العمل في حد ذاته هو تغيير تعريف الارتباط وضع "UseCookies" (أيملفات تعريف الارتباط هي المطلوبة) في شبكة الإنترنت.ملف التكوين:

<authentication mode="Forms">
  <forms loginUrl="~/Account/SignIn" cookieless="UseCookies"/>
</authentication>

وفقا بلدي التجارب ، القيام بذلك يجعل آثارها العمل في حد ذاته على حساب موقع الويب الخاص بك الآن تتطلب ملفات تعريف الارتباط بشكل صحيح.

تكون على علم بأن WIF يرفض أن تخبر المتصفح أن تنظيف ملفات تعريف الارتباط إذا كان wsignoutcleanup رسالة من STS لا يطابق عنوان url مع اسم التطبيق من IIS ، أعني القضية الحساسة.WIF يستجيب مع الأخضر موافق الاختيار ، ولكن سوف لا وإرسال الأمر إلى حذف ملفات تعريف الارتباط في المتصفح.

لذا تحتاج إلى إيلاء الاهتمام لهذه القضية من حساسية url.

على سبيل المثال ، ThinkTecture الهوية خادم يحفظ عناوين زيارة RPs في كعكة واحدة ، ولكنه يجعل كل منهم أقل حدة.WIF سوف تتلقى wsignoutcleanup رسالة في حالة انخفاض ومقارنتها مع اسم التطبيق في IIS.إذا كان لا يطابق ، حذف أي ملفات تعريف الارتباط ، ولكن تقرير "موافق" إلى المتصفح.إذن ، هذه الهوية الخادم كنت بحاجة لكتابة كل عناوين المواقع في شبكة الإنترنت.التكوين و جميع أسماء التطبيقات في IIS في أقل حال ، من أجل تجنب مثل هذه المشاكل.

لا تنسى أيضا أن تسمح طرف ثالث الكوكيز في المتصفح إذا كان لديك تطبيقات خارج نطاق فرعي من STS ، وإلا فإن المتصفح سوف يتم حذف ملفات تعريف الارتباط حتى لو WIF يقول له ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top