150

これに対して私の頭を少し長すぎた。FormsAuthentication.SignOutを使用してログアウトした後、ユーザーがサイトのページを閲覧できないようにするにはどうすればよいですか?私はこれがそれをすることを期待します:

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

しかし、そうではありません。URLを直接入力しても、ページを参照できます。私はしばらくの間、自分でロールするセキュリティを使用していなかったので、なぜこれが機能しないのかを忘れています。

4

23 に答える 23

217

FormsAuthentication.SignOut()呼び出し時に Cookie がクリアされず、新しいリクエストごとに認証されるため、ユーザーは引き続き Web サイトを閲覧できます。MS のドキュメントでは、Cookie がクリアされると書かれていますが、そうではありません。バグですか? とまったく同じでSession.Abandon()、cookie がまだ残っています。

コードを次のように変更する必要があります。

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

HttpCookieSystem.Web名前空間にあります。MSDN リファレンス

于 2009-08-20T15:22:50.833 に答える
23

x64igor と Phil Haselden による上記の投稿のうちの 2 つを使用して、これを解決しました。

1. x64igor は、ログアウトを行う例を示しました。

  • まず、ログアウトへの応答で空の Cookie を返すことにより、認証 Cookie とセッション Cookieをクリアする必要があります。

    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. Phil Haselden は、ログアウト後のキャッシュを防止する方法の上記の例を示しました。

  • Response を介してクライアント側でキャッシュを無効にする必要があります。

        // 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" ); 
    }
    
于 2012-02-15T01:35:27.027 に答える
19

内で web.config 認証セクションが適切に設定されていないように思えます。例については、以下を参照してください。

<authentication mode="Forms">
  <forms name="MyCookie" loginUrl="Login.aspx" protection="All" timeout="90" slidingExpiration="true"></forms>
</authentication>
<authorization>
  <deny users="?" />
</authorization>
于 2009-01-05T05:00:13.033 に答える
14

ここで重要なのは、「URLを直接入力すると...」と言うことです。

デフォルトでは、フォーム認証の下で、ブラウザはユーザーのページをキャッシュします。したがって、ブラウザのアドレスボックスのドロップダウンから直接URLを選択するか、入力すると、ブラウザのキャッシュからページを取得できます。サーバーに戻って認証/承認を確認することはできません。これに対する解決策は、各ページのPage_Loadイベント、またはベースページのOnLoad()でクライアント側のキャッシュを防ぐことです。

Response.Cache.SetCacheability(HttpCacheability.NoCache);

また、次のように電話することもできます。

Response.Cache.SetNoStore();
于 2010-03-22T00:26:52.480 に答える
12

私も以前これに苦労しました。

何が起こっているように見えるかについてのアナロジーは次のとおりです... 新しい訪問者 Joe がサイトに来て、FormsAuthentication を使用してログイン ページからログインします。ASP.NET は Joe の新しい ID を生成し、彼に Cookie を提供します。そのクッキーは家の鍵のようなもので、ジョーがその鍵を持って戻ってくる限り、鍵を開けることができます。各訪問者には、使用する新しいキーと新しいロックが与えられます。

FormsAuthentication.SignOut()呼び出されると、システムは Joe に鍵をなくすように指示します。通常、これは機能します。Joe は鍵を持っていないため、入ることができません。

ただし、ジョーが戻ってきて、なくした鍵を持っていれば、彼は元に戻されます!

私が知る限り、ASP.NET にドアのロックを変更するように指示する方法はありません。

私がこれに対処できる方法は、Joe の名前をセッション変数に記憶することです。彼がログアウトすると、私はセッションを放棄するので、彼の名前はもうありません。後で、彼が許可されているかどうかを確認するために、彼の Identity.Name を現在のセッションのものと単純に比較し、それらが一致しない場合、彼は有効な訪問者ではありません。

要するに、Web サイトの場合、User.Identity.IsAuthenticatedセッション変数を確認せずに依存しないでください。

于 2010-05-28T19:02:45.203 に答える
7

多くの検索の後、最終的にこれがうまくいきました。お役に立てば幸いです。

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>
于 2015-08-28T17:51:58.030 に答える
6

これは私のために働く

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());
    }
于 2011-05-26T19:06:09.227 に答える
5

この回答は技術的には 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

于 2016-12-27T18:43:03.853 に答える
3

ここでいくつかの提案を試してみましたが、ブラウザの戻るボタンを使用できましたが、メニュー選択をクリックすると、その [ActionResult] の [Authorize] トークンがログイン画面に戻りました。

ここに私のログアウトコードがあります:

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

ブラウザの戻る機能で戻って保護されたメニューが表示されましたが(私はまだ取り組んでいます)、アプリで保護されていることは何もできませんでした.

お役に立てれば

于 2012-01-24T13:07:34.343 に答える
3

投稿したコードは、フォーム認証トークンを正しく削除する必要があるように見えるため、問題のフォルダー/ページが実際には保護されていない可能性があります。

ログインする前にページにアクセスできないことを確認しましたか?

使用している web.config 設定とログイン コードを投稿できますか?

于 2009-01-05T04:58:59.730 に答える
3

このスレッドでほとんどの回答を試しましたが、うまくいきませんでした。これで終わった:

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

于 2013-07-10T10:49:35.097 に答える
3

私はすべてのページの基本クラスを作成しており、同じ問題に遭遇しました。次のようなコードがあり、機能しませんでした。トレースすることで、リダイレクトされることなく、RedirectToLoginPage() ステートメントから次の行に制御が渡されます。

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

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

2つの解決策があることがわかりました。FormsAuthentication.RedirectToLoginPage(); を変更します。することが

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

または追加して web.config を変更する

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

2 番目のケースでは、トレース中に、制御が要求されたページに到達しませんでした。ブレークポイントに到達する前に、すぐにログイン URL にリダイレクトされました。したがって、 SignOut() メソッドは問題ではなく、リダイレクト メソッドが問題です。

それが誰かを助けることを願っています

よろしく

于 2009-05-06T15:47:12.803 に答える
2

これは、 authentication > forms > Path プロパティをに設定したときに発生し始めましたWeb.config。それを削除すると問題が解決し、簡単FormsAuthentication.SignOut();にもう一度Cookieを削除しました。

于 2011-11-30T15:49:36.347 に答える
1

私は現在同様の問題を抱えており、私の場合と元のポスターの問題はリダイレクトが原因であると考えています。デフォルトでは、Response.Redirect によって例外が発生し、それがキャッチされてリダイレクトがすぐに実行されるまですぐにバブルアップします。これにより、変更された Cookie コレクションがクライアントに渡されないようになっていると推測しています。コードを変更して使用する場合:

Response.Redirect("url", false);

これにより、例外が防止され、Cookie がクライアントに適切に送り返されるように見えます。

于 2011-12-09T21:07:05.513 に答える
1

私にとっては、次のアプローチが機能します。「FormsAuthentication.SignOut()」ステートメントの後にエラーがあると、SingOut が機能しないと思います。

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

            return Redirect("~/");
        }
        return View();
     }
于 2016-07-12T12:08:12.220 に答える
1

SignOut() がチケットを適切に削除できなかったように見える同じ問題が発生しました。ただし、他のロジックがリダイレクトを引き起こした特定のケースでのみ。この 2 番目のリダイレクトを削除した後 (エラー メッセージに置き換えた後)、問題は解消されました。

問題は、ページが間違ったタイミングでリダイレクトされたため、認証がトリガーされなかったことです。

于 2009-08-29T20:26:42.587 に答える
1

あるサブドメイン (sub1.domain.com) からログインし、別のサブドメイン (www.domain.com) からログアウトしようとしている可能性があります。

于 2009-02-20T05:05:21.990 に答える
1

問題を理解するのに役立つ情報を追加したかったのです。フォーム認証では、Cookie または URL のクエリ文字列にユーザー データを格納できます。サイトがサポートする方法は、web.config ファイルで構成できます。

マイクロソフトによると

SignOut メソッドは、CookiesSupported が false の場合、Cookie または URL からフォーム認証チケット情報を削除します。

同時に、彼らは言う

アプリケーションが Cookie を使用しないフォーム認証用に構成されているかどうかを示す HttpCookieMode 値の 1 つ。デフォルトは UseDeviceProfileです

最後に、UseDeviceProfile に関しては、次のように述べています

CookieMode プロパティが UseDeviceProfile に設定されている 場合、現在のリクエストのブラウザが Cookie と Cookie によるリダイレクトの両方をサポートしている場合、CookiesSupported プロパティは true を返します。それ以外の場合、CookiesSupported プロパティは false を返します。

これをすべて組み合わせると、ユーザーのブラウザーによっては、既定の構成で CookiesSupported がtrueになる場合があります。これは、SignOut メソッドが Cookie からチケットをクリアしないことを意味します。これは直感に反するようで、なぜこのように機能するのかわかりません。SignOut は、どのような状況でも実際にユーザーをサインアウトすることを期待しています。

SignOut を単独で機能させる 1 つの方法は、web.config ファイルで Cookie モードを「UseCookies」に変更することです (つまり、Cookie が必要です)。

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

私のテストによると、これを行うと、サイトが適切に機能するために Cookie が必要になり、SignOut が単独で機能するようになります。

于 2015-11-24T14:03:46.363 に答える
0

Session.abandon() を実行して Cookie を破棄すると、かなりうまくいきます。私は mvc3 を使用していますが、保護されたページに移動してログアウトし、ブラウザの履歴を参照すると問題が発生するようです。大したことではありませんが、それでもちょっと面倒です。

ただし、Web アプリでリンクをたどろうとすると、正しい方法で機能します。

ブラウザのキャッシュを行わないように設定するのが良い方法かもしれません。

于 2011-06-24T13:52:55.010 に答える
0

IE を使用してこの動作をテストまたは確認していますか? IE がキャッシュからこれらのページを提供している可能性があります。IE でキャッシュをフラッシュするのは非常に難しいため、多くの場合、ログアウトした後でも、「保護された」ページのいずれかの URL を入力すると、以前にキャッシュされたコンテンツが表示されます。

(別のユーザーとしてログインした場合でもこの動作が見られ、IEはページの上部に古いユーザーのユーザー名で「ようこそ」バーを表示します。最近では、通常、リロードによって更新されますが、永続的である場合、それはまだキャッシングの問題である可能性があります。)

于 2009-01-05T05:40:40.737 に答える
-2

STS からの wsignoutcleanup メッセージが IIS からのアプリケーションの名前の URL と一致しない場合、WIFはブラウザーに Cookie をクリーンアップするように指示することを拒否することに注意してください。つまりCASE SENSITIVEです。WIF は緑色の OK チェックで応答しますが、Cookie を削除するコマンドをブラウザーに送信しません。

そのため、URL の大文字と小文字の区別に注意する必要があります。

たとえば、ThinkTecture Identity Server は訪問した RP の URL を 1 つの Cookie に保存しますが、すべて小文字にします。WIF は小文字の wsignoutcleanup メッセージを受け取り、IIS のアプリケーション名と比較します。一致しない場合、Cookie は削除されませんが、ブラウザーに OK が報告されます。そのため、この Identity Server では、このような問題を回避するために、web.config のすべての URL と IIS のすべてのアプリケーション名を小文字で記述する必要がありました。

また、アプリケーションが STS のサブドメイン外にある場合は、ブラウザーでサード パーティの Cookie を許可することを忘れないでください。そうしないと、WIF が許可したとしても、ブラウザーは Cookie を削除しません。

于 2013-05-31T10:32:07.030 に答える