WebSurfer's Home

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

ReportViewer と Session

by WebSurfer 2015年9月7日 15:22

ReportViewer は Session を使うという話を書きます。

IE で ReportViewer を表示

上の画像は、ReportViewer を使用してパラメーターを含む詳細 (RDLC) レポートを作成する というチュートリアルに従って作ったものですが、どこにも明示的に Session を使うようなコードは含まれていません。

ところが、このページを要求すると、下の画像(Fiddler2 でキャプチャしたもの)のように応答ヘッダにセッション Cookie が設定され(画像の赤枠で囲った部分)、Session の使用が開始されます。

応答ヘッダのセッション Cookie

知ってました? 実は自分は知らなかったです。(汗) 最近まで ReportViewer と Session は何の関係もないと思っていましたが、MSDN フォーラム でのやり取りを通じてこのことを知りました。

MSDN Blog の記事 Did Your Session Really Expire? によると、ReportViewer は再生するのが簡単ではないデータを保存するのに Session を使うとのことです。

そして、ポストバックの際などに期待したデータが Session にないと AspNetSessionExpiredException をスローするとのことです。

AspNetSessionExpiredException 例外がスローされる原因として次のことが書かれています:

  1. 本当にセッションがタイムアウトした。(例:ping をかけてタイムアウトにならないようにしているが、サーバーが忙しいとか接続が不安定で失敗した)
  2. 要求を処理しているサーバーにセッションがない。(例:セッションのモードが InProc で、Web Garden / Farm 構成になっているとか、ワーカープロセスがリサイクルされた)
  3. ブラウザがクッキーを受け付けない設定になっている。

上記 1 のことは MSDN ライブラリの ReportViewer.KeepSessionAlive プロパティ に書かれています。デフォルトは true で、セッションがタイムアウトしないように自動的に ping がかかります。

上記 2 のワーカープロセスのリサイクルによる Session の消失を防ぐためには、Session の格納場所を InProc ではなく、StateServer または SQLServer にするのがよさそうです。商用に使うのであれば、InProc モードは論外という意見もあるようですし。設定方法の詳細は MSDN ライブラリの記事 セッション状態モード を見てください。

Tags: ,

ASP.NET

IE でアップロードする際のファイル名

by WebSurfer 2015年8月6日 11:52

Internet Explorer (IE) でファイルをアップロードする際、ファイル名にフルパスが付与されることがあります。

IE のセキュリティ設定

上の画像は IE9 のローカルイントラネットゾーンのセキュリティ設定ですが、赤枠で囲んだ部分が示すように、デフォルトで [有効にする] が選択されており、送信データの Content-Disposition: ... filename="xxx" の xxx はフルパスになります。

インターネットゾーンでも IE7 以前はデフォルトで [有効にする] が選択されているそうです(未確認です)。ちなみに IE9 ではデフォルトで [無効にする] が選択されているのは確認しました。

知ってました? 実は自分は最近まで知らなかったです。(汗) 調べていませんが、他のブラウザでも同様な問題があるかもしれません。

今までその問題に遭遇したことはなかったのですが、それはファイル名の取得に FileUpload.FileName プロパティ を使っていたので、問題を免れていたと言うことのようです。

上のリンク先の MSDN ライブラリの「解説」に、"FileUpload コントロールを使用して、アップロードする、クライアント上のファイルの名前を取得します。FileName プロパティが返すファイル名には、クライアント上のファイルのパスが含まれません。" と書いてありますね。

ちなみに、HttpPostedFile.FileName プロパティ では、ブラウザからフルパスでファイル名が送信されてくれば、結果はフルパスになります。

なので、HttpPostedFile.FileName プロパティを使わざるを得ない場合は(複数ファイルを同時アップロードするような場合が該当するでしょうか)、Path.GetFileName メソッド を使ってファイル名を取得するのがよさそうです。

そういえば、昔ネット上で見かけてサンプルコードに Path.GetFileName メソッドを使った例が多々あったような記憶があります。

Tags: ,

Upload Download

非ドメインユーザーの誘導

by WebSurfer 2015年7月9日 22:03

イントラネット内の Active Directory ドメイン環境で、統合 Windows 認証によってシングルサインオンが実現されているサイトがあって、そこに非ドメインユーザーがアクセスしてきたとき、そのユーザーを誘導する(例えば、ドメインユーザー専用である旨通知するとか、別のサイトにリダイレクトする)方法について書きます。(MSDN フォーラム の話をまとめたものです)

Windows 認証のやり取り

クライアントが Windows 認証サイトにアクセスしてくると、認証手続きが始まって、認証が成功し、要求したページが表示されるまで、上の画像(キャプチャツール Fiddler2 のもの。NTLM の場合)のように要求 / 応答がやり取りされます。

NTLM の場合、具体的には以下のステップ 1 ~ 9 のようになります。上の Fiddler2 の画像の左側のウィンドウのライン #1 がステップ 1 ~ 4、#2 がステップ 5 ~ 6、#3 がステップ 7 ~ 8 に該当します。

Kerberos の場合は NTLM より一回ラウンドトリップが少なくなります。以下のステップ 5 ~ 6 がないという感じです。(あくまで「感じ」です。詳しくは MSDN Blog の記事 Two easy ways to pick Kerberos from NTLM in an HTTP capture を見てください)

  1. ブラウザからページ(この例では Default.aspx)を GET 要求。
  2. サーバーは 401 応答を返す。その際、サーバー側で AuthenticateRequest, EndRequest イベント発生。イベントハンドラで User は null になる。
  3. クライアントには認証ダイアログが表示される。
  4. ユーザー名とパスワード入力して[OK]ボタンをクリック。
  5. ブラウザは再度 Default.aspx を GET 要求。
  6. サーバーは 401 応答を返す。この時はサーバー側で AuthenticateRequest, EndRequest イベントは発生しない。
  7. ブラウザは再々度 Default.aspx を GET 要求。
  8. サーバーは 200 応答を返す。サーバー側で AuthenticateRequest, EndRequest イベント発生。イベントハンドラで User はログインユーザーの WindowsPrincipal になる。
  9. ブラウザには Default.aspx が表示される。

統合 Windows 認証の場合、How IIS authenticates browser clients によると、認証済み / 未認証ユーザーの手続きの違いは、Kerberos でも NTLM でも、ステップ 3 ~ 4 の有無ということです。(自分の PC を立ち上げた時にドメインにログイン済みのユーザーの場合はステップ 3 はスキップ、ステップ 4 は自動的に行われる)

ステップ 3 でダイアログが表示された時、非ドメインユーザーができることは、[キャンセル]または[X]ボタンをクリックするか、3 回ユーザー名とパスワードを入力して認証に失敗するかですが、いずれの場合でも標準のエラーページが表示されます。

従って、アクセスしたサイトがドメインユーザー専用であることを説明するなどしたカスタムエラーページを作り、標準のエラーページと差し替えることによって、非ドメインユーザーを適切に誘導することができます。

自分の開発環境の IIS7 の場合ですが、applicationHost.config ファイルの httpErrors 要素に、カスタムページ ErrorPage.htm を以下のように設定することで差し替えることができます。

(注:自分の環境では applicationHost.config で httpErrors に対しては overrideModeDefault="Deny" と設定されているので web.config では httpErrors を設定できませんが、IIS7.5 では web.config で設定可能とのことです。ご自分の環境で確認ください)

<location path="Default Web Site/WindowsAuthentication">
  <system.webServer>
    <httpErrors errorMode="Custom">
      <remove statusCode="401" />
      <error statusCode="401" 
        path="C:\inetpub\custerr\ja-JP\ErrorPage.htm"
        responseMode="File" />
    </httpErrors>
  </system.webServer>
</location>

認証ダイアログが表示された直後に[キャンセル]または[X]ボタンをクリックした場合は、差し替えたカスタムエラーページが表示されます。

しかし、自分の環境で試した限りですが、一旦認証ダイアログに ID / パスワードを入力して認証に失敗した後に返ってくるエラーページは最初の標準エラーページとは異なり、これをカスタムエラーページに差し替えることはではできませんでした。

(注:IIS7.5 ではカスタムエラーページに差し替えられたとの報告があります。その場合は以下の対応は不要となります。ご自分の環境で確認ください)

その場合、EndRequest イベントで User.Identity.IsAuthenticated が true、Response.StatusCode が 401 になることで判定でき、以下のようにすることにより対応できます。ステップ 5 ~ 6 ではイベントは発生しないのでこのやり方でうまくいきます。

void Application_EndRequest(object sender, EventArgs e)
{
  if (User != null)
  {
    bool auth = User.Identity.IsAuthenticated;
    int statusCode = Response.StatusCode;

    if (auth && statusCode == 401)
    {
      HttpContext.Current.Response.Redirect("リダイレクト先");
    }
  }
}

ちなみに正しい ID / パスワードが入力され認証に成功した場合は Response.StatusCode が 200 になりますので、リダイレクトされてしまうということはありません。

ユーザー名とパスワードを入力するダイアログが表示されるのは避けられないとうところが難ありですが、それでよければ上記の案で非ドメインユーザーを適切に誘導することができそうです。興味があればお試しください。

なお、統合 Windows 認証は IE2 以降でのみサポートされているということなので(参考:認証について)、User Agent を調べてブラウザが IE 以外なら即リダイレクト等の処置をとってもいいかもしれません。

Tags: ,

Authentication

About this blog

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

Calendar

<<  2024年4月  >>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar