Shizuku Blog ~ techbank.jp版~

~女性エンジニア けろ-みおの苦悩~

ログイン | ID登録 | ヘルプ


ニュース


当Blogにについて

当Blogは、けろ-みおが備忘録として活用しているBlogになります。掲載している内容について、必ずしも正しい情報を公開しているわけではありませんので予めご了承下さい。
当Blogで公開している記事に対して、質問がある場合は、techbank.jp掲示板でお問い合わせ頂くか、techbank.jp ID申請を行い、IDを作成した段階で当Blogにコメントする等してください。
原則、正体がわからない方からのBlogコメント欄を使ったご質問・ご指摘は、承っておりません。
コメント投稿・公開(承認)基準につきましては、 当Blogのコメント投稿についてをご確認ください。
テクニカルコミュニティ(techbank.jp)に設置しているBlogということもあり、皆様のご理解とご協力の程、宜しくお願いします。

自己紹介

けろ-みおと申します。「techbank.jp」の副管理人をやっております。

MVP Profile

0







けろ-みおの関連サイト





このBlogの人気度
フィードメーター - techbank.jpコミュニティ

techbank.jp Blog全体と近いBlog
あわせて読みたいブログパーツ

このBlogと近いBlog
あわせて読みたいブログパーツ

Blog購読者数
スカウター : techbank.jp







[ASP.NET] : ファイルを外部サーバーやネットワーク越しに保存する際の基本的な設定と概要

 

この手の質問って、いろんな掲示板やフォーラムで回答されていますが、

綺麗にまとめているサイトが少ないなと思ったので、今更感バリバリですが、今後のために情報をまとめておこうと思います。

 

まず、この記事を参考される方は、下記の環境&現象に陥った方を前提とさせて頂きます。

 

1. Windows Server 2003 を使用している

2. IIS 6 を使用している ( IIS7 用については、次回エントリでご紹介します。GUI操作でだいたいできるレベルなので)

3. ASP.NET 2.0 を使用している

4. Webサーバーとは別の場所に、ASP.NETで処理したファイル(画像やCSVファイル)を

       別サーバー(以下、外部ファイルサーバーとする)に配置する予定のある方(ただし、FTP転送ではない)

5.Webサーバーと外部ファイルサーバーのネットワークが、同じネットワークセグメントにあることを前提とします。

 

また、下記の例外が出てハマってしまった方も対象と致します。

 

1.Webサーバー →  外部ファイルサーバー に、ネットワークドライブ(例:Z:\ 、S:\ 等)を経由してI/O した際、

「System.IO.DirectorynotfoundException」例外が発生してしまった方

 

2.Webサーバー →  外部ファイルサーバー に、ネットワークドライブまたはUNCパス書式を使って、I/Oした際、

「System.IO.IOException」例外が発生してしまった方

 

それでは、上記のような問題にハマった方は、是非、下記をご覧ください。

 

A. ASP.NETの「セキュリティ アーキテクチャ」を軽くで良いので覚えましょう

 

今回のように、外部サーバーにファイルのI/Oを行うケースに限った場合は、

下記のようなイメージでIISとASP.NETは、ファイル等のリソース類にアクセスします。

(ちょっと大雑把なな図ですいません。厳密に書くともっと細かく書けるんですが)

図面1

( クリックすると、拡大表示できます )

 

用語が分からない方もいると思うので、少しだけ解説します。

 

・ 「アクセストークン」とは、アクセスするための許可情報みたいなものだと思って下さい。

・ 「匿名アクセス」 と 「認証済みアクセス」は、IISで設定した「認証方法」のことです。

image

・ 「フォーム認証」は、ASP.NETなどで作成した独自認証ページ等から、認証する仕組みのことです。

 

今回のケースの場合、「⑦目的ファイル等の各種リソース類」は、「外部ファイルサーバーにあるファイル」ということになるので、

「ASP.NET ワーカープロセスが、アクセスできるリソースでなければならない」ということが上記の図でわかります。

しかし、ASP.NETの既定では、「ASPNET」または「NETWORK_SERVICE」(Windows 2003 Server の場合)

というWindows ID と、アクセストークンで実行されているため、「ASPNET」または「NETWORK_SERVICE」が

アクセスできるリソースでなければ、当然アクセスすることができません。

この手の話は、他のWebサイトや掲示板、一般的な書籍でも紹介されているので、有名な話ですね。

 

そうなると、外部ファイルサーバーにファイルを読み書きできないの?諦めなきゃいけないの?

という話になりますが、ASP.NETワーカープロセス(aspnet_wp.exe)に要求を出したWindows IDが、

外部ファイルサーバーにアクセスできる権限(Windows ID) と同じID、もしくは同種のアクセストークンであれば、

この問題を解決することができます。

 

このように、特定のファイルやディレクトリ等のリソースにアクセスできるアクセストークンを持つ特定のWindows ID等を使って、

ASP.NETワーカープロセスがリソースにアクセスできるよう定義することを 「偽装」と呼んでいます。

 

B. 偽装の設定方法

 

web.config の 「system.web」タグ内に、「identity」タグを指定するようにすると、偽装できるようになります。

<identity impersonate="true" />   

 

しかし、この設定だと偽装したWindows IDが、

 

IIS が匿名アクセスを使ってない場合: 認証に使用したWindowsユーザに偽装

IISが匿名アクセスを使っている場合:「IUSR_<マシン名>」ユーザで偽装

 

するので、相手先である 外部ファイルサーバーが、必ずしも偽装したWindows IDに対して権限を持っているとは限りません。

そのため、外部ファイルサーバーにもアクセスができ、ASP.NETアプリケーションも実行できる固定のWindows ID

(または、同種のアクセストークンを持つ別のWindows  IDでも良い) を明示的にidentity タグに指定します。

 

<identity impersonate="true" userName="kero-mio\Administrator" password="password_1031" />

<!--
userName は、(マシン名 or ADドメイン名 or 同一ワークグループに存在する場合はワークグループ名を指定しない)\(偽装に使用するWindows ID) を指定する
password は、userName に紐づくパスワードを指定する 

TODO:userName やパスワードは、レジストリに格納し、レジストリから取得することもできます。
--> 

 

詳しい偽装設定の詳細については、MSDNのサイトをご覧ください。

http://msdn.microsoft.com/ja-jp/library/xh507fc5(VS.80).aspx

 

C. ネットワークドライブ経由ではなく、UNC PATHで外部ファイルサーバーに接続する

 

ASP.NETアプリケーションで「System.IO」名前空間にあるクラスやメソッドを何も気にせず使用し、

さらに対象ファイルの置き場がネットワークドライブ(例:Z:\ や S:\ 等)だった場合、「System.IO.DirectorynotfoundException」例外が発生します。

 

System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share) 
System.IO.File.WriteAllBytes(String path, Byte[] bytes)  

 

「web.configで偽装設定したのに、なんで?」と思われると思いますが、実は、System.IO名前空間にあるクラスやメソッドは、

ネットワークドライブに対するI/Oに対応していないのが原因で、「System.IO.DirectorynotfoundException」が発生しています。

可能であれば、UNCパス形式(例:\\servername\directory\) で外部ファイルサーバーにアクセスして頂きたいのですが、

業務の事情や保守の都合でUNCパス形式が嫌というお客様がもしいらっしゃるのであれば、「WNetGetConnection」というWinAPIが

あるので、「WNetGetConnection」でネットワークドライブに接続した後、「System.IO」名前空間にあるクラスやメソッドを使って

ファイルやディレクトリ操作することもできます。

(そういえば、「WNetGetConnection」って、しばらく使ってないなぁ・・・)

 

WNetGetConnection の使い方 (C++のリファレンスですが): http://msdn.microsoft.com/ja-jp/library/cc447035.aspx

 

ただし、ASP.NETアプリケーションから、「WNetGetConnection」APIを使ってネットワークドライブに接続するのは、

セキュリティ的にもアーキ的にもお勧めしかねるので、可能であれば、

「「UNCパス形式」で外部ファイルサーバーにアクセスする」作りにしておいてください。

 

D. ProcessModel と identity の違い

 

今回のように外部ファイルサーバーアクセスエラーが発生すると、意味がわからないまま、

machine.config で定義されている ProcessModel と 、web.config に設定したidentity、

両者に同じuserName, Password を設定し、とりあえず動くからOK!にしている人も結構いらっしゃるんじゃないかと思います。

 

MSDNでの書き方がASP.NETに不慣れな方からみると、混乱しやすいのかなぁと思い、大雑把にまとめてみました。

 

    概要   主な定義場所   対象
ProcessModel マシン単位(Webサーバー)で、ASP.NET を動かすための 必要最小限の権限を設定するのに使用する。 既定では、ASPNET、または、NETWORK_SERVICE (Windows 2003 の場合)のWindows ID で実行されるように 作られていますが、特にuserName, Password の設定は不要 machine.config ASP.NET ワーカープロセス(Aspnet_wp.exe),
ASP.NET State Server(aspnet_state.exe)
※早い話がマシン内に設置されている
すべてのWebアプリケーション
  Identity Webアプリケーション単位で、ASP.NET を動かすための 権限を設定するのに使用する。Web.config に identity の 設定がない場合はmachine.config にある ProcessModel の設定内容がそのまま使用される web.config 配置しているWebアプリケーション内

 

ProcessModelには、ASP.NET が必要最低限の動作が行えるような弱い権限を持つWindows IDを設定しておき、、

Identity には、ProcessModel で設定した以上の権限を持つWindows IDを設定しておくと良いでしょう。

ただし、他のWebサイトにもまったく同じ偽装を施したい場合は、ProcessModelでuserNameとPasswordを設定するのも良いかなと思います。

そして、今回のように、外部ファイルサーバーにアクセスするだけのものであれば、「Identiy」に偽装設定しておくのが良いかなと思います。

もし、ProcessModel と Identity 両方に同じuserName, password を設定しなければ動かなかったという方が

いらっしゃいましたら、けろ-みお までお知らせ下さい。

 

※記事はある程度、裏を取ってからUPしているつもりですが、

文面ミスによって、嘘の情報を流してしまっている可能性もあります。その場合は、Blogコメント欄でご指摘下さい。

Published 2009年7月6日 18:31 けろ-みお
分類: ,

コメント

このBlogに対するコメントはありません

コメントを残す

(必須) 
(必須) 
(オプション)
(必須)