WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

Forms 認証のログイン・ログオフ動作

by WebSurfer 2011年8月3日 22:14

Froms 認証のログイン・ログオフ動作

認証クッキーを使用した場合における Forms 認証のログインとログアウト動作で、サーバーとクライアントのやり取りがどのように行われているか調べてみましたので、備忘録として書いておきます。

ログアウト操作で、認証クッキーを削除するため、ポストバックして同じページにリダイレクトをかけていることと、ロール名クッキーの追加と削除が認証クッキーより 1 ステップ遅れるのが新しい発見でした。

認証クッキーを使用せず、代わりに URL に認証チケットを追加して送るケースではどうなっているかは別途調べる予定です。

***** ログイン *****

  1. 匿名アクセスが許可されているあるページ(ここでは default.aspx とする)において、ログインしていない状態から LoginStatus をクリックする。
  2. JavaScrip が起動してポストバック(default.aspx への POST 要求)がかかる。この時、サーバーに送信される隠しフィールド __EVENTTARGET に LoginStatus の UniqueID が設定される(これにより、サーバーはログイン要求であると認識するらしい)。
  3. サーバーからリダイレクト指示(HTTP/1.1 302 Found)が返ってくる。応答ヘッダーに含まれる Location(リダイレクト先)は web.config で指定されたログインページ(ここでは login.aspx とする)となる。
  4. リダイレクト指示を受けて、ブラウザは login.aspx を GET 要求する。
  5. サーバーから応答(login.aspx)が返ってくる。
  6. ユーザーが ID とパスワードを入力して[ログイン]ボタンをクリックする。
  7. [ログイン]ボタンのクリックで login.aspx にポストバックがかかる。
  8. サーバーからリダイレクト指示(HTTP/1.1 302 Found)が返ってくる。応答ヘッダーに含まれる Location は default.aspx となる。この時、サーバーからの応答ヘッダーには認証クッキーが含まれる。(この時点ではロール名クッキーは送られないので注意)
  9. リダイレクト指示を受けて、ブラウザは default.aspx を GET 要求する。この時、上のステップで受信した認証クッキーを要求ヘッダーに含める。
  10. サーバーから応答(default.aspx)が返ってくる。認証クッキーが要求ヘッダーに含まれているので、ユーザーは認証済みとなる。(この時点で応答ヘッダーにロール名クッキーが含まれて送られてくる)

***** ログアウト *****

  1. あるページ(default.aspx とする)で、ログインしている状態から LoginStatus をクリック。
  2. JavaScrip でポストバック(default.aspx への POST 要求)がかかる。この時、サーバーに送信される隠しフィールド __EVENTTARGET には LoginStatus の UniqueID が設定される(これにより、サーバーはログアウト要求であると認識するらしい)。
  3. サーバーからリダイレクト指示(HTTP/1.1 302 Found)が返ってくる。ただし、リダイレクト先は同一ページ(Location は default.aspx)となる。この時、認証クッキーを削除するため、応答ヘッダの Set-Cookie は、認証クッキーを空にして、expires を過去の日時に設定している。
  4. ブラウザは default.aspx を GET 要求する。この前のステップの、応答ヘッダの Set-Cookie の設定により、認証クッキーは要求ヘッダーには含まれなくなる。(ただし、ロール名クッキーはこの時点ではまだ要求ヘッダーに含まれている)
  5. サーバーから応答 (default.aspx) が返ってくる。ユーザーはログアウト状態となる。この時、ロール名クッキーを削除するため、応答ヘッダの Set-Cookie で、ロール名クッキーを空にして、expires を過去の日時に設定している。

なお、Windows 認証の場合は、先の記事 Windows 認証でのロール に示した Windows OS の認証ダイアログを使います。従って、Web ページにはログイン画面は実装できませんし、ログイン操作も Forms 認証とは異なります。

また、ログアウトについても、Windows 認証の場合は一旦ログインしたユーザー情報はブラウザを閉じるまで保持され続けるので、Forms 認証とは異なり、Web ページにログオフ機能は実装できません。

Tags:

Authentication

Forms 認証のタイムアウト判定

by WebSurfer 2010年7月30日 08:37

あまり役に立たないかもしれませんが、ASP.NET 標準の Forms 認証システムで、認証チケットが期限切れになっているかどうかを判定するという話です。なお、前提条件としてクッキーが有効になっていることを想定しています。

例えば、一旦認証を受けたユーザーが、ログオフせず、ブラウザを立ち上げたまま、長時間席を外すなどして、タイムアウトに設定した時間を超えてアクセスしなかった場合を考えてください。

ユーザーが席に戻ってきて再度アクセスした場合、アクセスしたページに匿名アクセスを許可してなければ、ログインページにリダイレクトされるというのが Forms 認証の通常の設定です。

そこで、ユーザーに認証チケットが期限切れとなっていることを知らせるにはどうしたらいいでしょうか?

User.Identity.IsAuthenticated ではダメです。認証されているか否かは判定できますが、認証チケットが期限切れかどうかはわかりませんから。

一旦認証を受けたが、認証チケットが期限切れになっているというのは、サーバー側では以下の条件で判定できるはずです。

  • 要求 HTTP ヘッダーに認証クッキーが含まれる。
  • 認証クッキーの中の認証チケットが期限切れ。

認証クッキーと認証チケットは違うことに注意してください。クッキーはチケットの入れ物に過ぎません。認証チケットの有効期限は、認証クッキーの Value の中に入っている情報の一つです。HttpCookie.Expires ではありません。

一般的に、一旦認証クッキーの発行を受ければ、セッションが切れない限り(注)、次の要求の時にブラウザはサーバーにクッキーを送ります。(注:認証クッキーを「永続化」している場合は話が違ってきます。詳��くは別の記事「Froms 認証クッキーの永続化」を見てください)

認証クッキーを取得し、その Value を復号して認証チケットを取得し、ユーザー名、期限切れか否かなどの情報を取得できます。それで上記の 2 つの条件を確認できます。例えば、ログインページにリダイレクトされたときに期限切れを知らせる場合は、Global.asax で以下のようにします(もしくは HTTP Module を作る)。

void FormsAuthentication_Authenticate(object sender, 
  FormsAuthenticationEventArgs args)
{
  // "/login.aspx" は実際に合わせて適宜変更してください。
  if (Request.CurrentExecutionFilePath != "/login.aspx")
  {
    return;
  }

  string cookieName = FormsAuthentication.FormsCookieName;
  HttpCookie authCookie = Context.Request.Cookies[cookieName];

  if (null == authCookie)
  {
    return;
  }

  FormsAuthenticationTicket authTicket = null;
  try
  {
    authTicket = FormsAuthentication.Decrypt(authCookie.Value);
  }
  catch (Exception ex)
  {
    return;
  }

  if (null == authTicket)
  {
    return;
  }

  if (authTicket.Expired)
  {
    // 知らせるための処置を書く。例えば下記:
    Context.Response.Write("<h1><font color=red>" +
      "Forms Authentication Ticket Expired" +
      "</font></h1><hr>");
  }
}

認証チケットが期限切れの場合、FormsAuthenticationModule が認証クッキーを削除しているようで、タイミングによっては認証クッキーは取得できないので注意してください。

従って、認証クッキーを取得できるのは、FormsAuthenticationModule.Authenticate イベント以前のタイミングになります。

Tags: ,

Authentication

ブログのページを開設しました

by WebSurfer 2010年5月3日 16:53

BlogEngine.NET のホームページ

2010/5/1 にホームページの中にブログを開設しました。

中身は自分で作ったわけではなく、 BlogEngine.NET というサイトから、2010/4/30 時点での最新版 1.6.1 を入手して、既存の自分のホームページに追加しただけです。 (「追加しただけ」といっても、それなりの設定は必要ですが)

BlogEngine.NET を選んだ理由は、ASP.NET ベースの Web アプリケーションだからです。既存の自分のホームページも ASP.NET ベースなので統合するのが簡単そうだったし、ASP.NET に関する知識があればカスタマイズすることも可能と思ったからです。

特に、BlogEngine.NET は ASP.NET Forms 認証機能を持っていて、それを自分のホームページの既存の Forms 認証システムにシームレスに統合できそうな点にひかれました。

備忘録として、どのように既存のホームページに BlogEngine.NET を追加したかの概略を書いておきます。

  • このホームページは ActiveWeb というホスティングサービス会社の Win2008 というサービスを利用しています。まずそこに、ホスティングサービス会社が提供しているツールを利用して、仮想ディレクトリを作成します。
  • BlogEngine.NET のダウンロードサイトから Web 版(2010/5/3 時点での最新版 BlogEngine.NET 1.6.1 (web).zip)をダウンロードして解凍し、上記の仮想ディレクトリに丸ごとアップロードします。
  • ストアには、デフォルトの xml ファイルではなく SQL Server を使うので、既存のデータベースファイルに BlogEngine に必要なテーブルを追加します。これは、ホスティングサービス会社が提供しているツール myLittleAdmin を利用し、ダウンロードしてきた Web 版の setup\SQLServer フォルダに含まれているクエリを走らせて行います。
  • ストアに SQL Server を使えるように web.config を変更します。その方法は、Codeplex のサイトの Database Blog Provider が参考になると思います。ただし、接続文字列の内容や connectionStringName を全くそのとおりにしたのでは当然ダメで、自分のホームページの既存の設定にあわせて修正する必要はあります。
  • ログインの際のユーザー認証と承認に、ASP.NET Forms 認証の既定のプロバイダ SqlMembershipProvider, SqlRoleProvider を使用するように web.config の設定を変更します。 その方法は、CodePlex のサイトの MSSQLMembershipProvider / MSSQLRoleProvider が参考になると思います。これも、接続文字列などを自分のホームページの既存の設定にあわせて修正する必要があります。
  • 最後に、ユーザーがホームページ本体とブログのページを行き来する際に再認証を受ける必要をなくするための設定を行います。そのためには、ホームページ本体とブログ両方の web.config で name, protection, path, validationKey, validation, decryptionKey および decryption を同じにします。これは、MSDN ライブラリのアプリケーション間のフォーム認証が参考になりました。

ここまでやって、とりあえず表示することができるようになりました。

IIS のアプリケーションプールのマネージパイプラインモードは、今のところ「統合」のままです。「クラシック」にしないと "some of the software will fail in strange ways" と書いてありましたが、まだそういう問題に遭遇していません。 BlogEngine はホームページ本体とは別アプリケーションなので、それのみ「クラシック」にする方法はないか、ホスティングサービス会社に聞いてみる予定です。

うわさに聞く日本語の文字化けの問題は、ストアをデフォルトの xml ファイルにした場合は起こるようですが、SQL Server を利用する設定では、今のところ問題ないです。このまましばらく様子を見たいと思います。

Tags:

BlogEngine.NET

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年5月  >>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

View posts in large calendar