C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: ASP.Netで実行時エラー0x80070005 (E_AC


(過去ログ 137 を表示中)

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■80668 / inTopicNo.1)  ASP.Netで実行時エラー0x80070005 (E_AC
  
□投稿者/ Sasaki (8回)-(2016/08/01(Mon) 20:27:27)

分類:[ASP.NET (C#)] 

お世話になっております。
ActiveDirectoryのユーザーがパスワードを忘れた際に、システム管理者が不在のときでも、自力でリセットできるようにするために、
イントラネット内のWebサイトからパスワードをリセットする仕組みを検討しています。
(セキュリティが低下するので、メールなどを利用して本人確認をする仕組みを別途検討しています。)

[VS Express 2013 for Desktop]の[C#コンソールアプリ]で作成したテストプログラムでは、パスワードをリセットすることができたのですが、
同じ処理を[VS Express 2015 for Web]の[Webサイト]で実行すると、[UnauthorizedAccessException]が発生しました。
おそらく権限が足りないと思われるのですが、エラーを解消させることは可能でしょうか。
それとも、C#コンソールアプリでできたからといって、ASP.Net + IISでもできるとは限らないものなのでしょうか?
何を確認すればよいか、もしくはどのようにIISの設定をすればよいかなど、アドバイスいただけると助かります。

以下に、エラーが発生したサンプルを記します。
◇サンプル(Test.aspx)
------------------------ ここから
    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.DirectoryServices" %>

    <!DOCTYPE html>

    <script runat="server">
        void Page_Load(object sender, EventArgs e) {
            testLabel.Text += "--- Start --- " + (DateTime.Now).ToString("yyyy/MM/dd HH:mm:ss") + "<br />";

            try {
                // 実行時ユーザの表示
                testLabel.Text += "CurrentUser:[" + System.Security.Principal.WindowsIdentity.GetCurrent().Name + "]" + "<br />";

                // ディレクトリサービスの利用
                using(DirectoryEntry directoryEntry = new DirectoryEntry(@"LDAP://dc=xxxx,dc=local")) {	// ←ドメインの指定(ドメイン名="xxxx.local")
                    if(directoryEntry != null) {
                        // ユーザーを検索
                        DirectorySearcher searcher = new DirectorySearcher(directoryEntry);
                        searcher.Filter = "(sAMAccountName=" + "XX999999" + ")";						// ←パスワードを変更するユーザーIDを指定
                        SearchResult result = searcher.FindOne();
                        if(result != null) {
                            using(DirectoryEntry userEntry = result.GetDirectoryEntry()) {
                                // パスワードのリセット
                                userEntry.AuthenticationType = AuthenticationTypes.Secure;
                                userEntry.Username = "AdminUserID";										// ←管理者権限をもっているアカウントのユーザーID
                                userEntry.Password = "AdminPassword";									// ←管理者権限をもっているアカウントのパスワード
                                userEntry.Invoke("SetPassword", new object[] { "Password_Xx99!&" });	// ←変更後のパスワードを指定(ここでExceptionが発生しています。)
                                // ↑↑↑ "SetPassword"ではなく、"ChangePassword"なら現在のパスワードも引数に指定することで、パスワードの変更ができています。
                                userEntry.CommitChanges();
                            }
                        }
                    }
                }
            }
            catch(Exception exception) {
                testLabel.Text += exception.ToString() + "<br />";
            }
            finally {
                testLabel.Text += "--- End --- " + (DateTime.Now).ToString("yyyy/MM/dd HH:mm:ss") + "<br />";
            }
        }
    </script>

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>Test</title>
    </head>
    <body>
        <hr />
        <asp:Label runat="server" id="testLabel"></asp:Label>
        <hr />
    </body>
    </html>
------------------------ ここまで

◇以下が実行結果です。(適当に改行を入れています。)
	--- Start --- 2016/08/01 19:24:30
	CurrentUser:[IIS APPPOOL\DefaultAppPool]
	System.Reflection.TargetInvocationException: 呼び出しのターゲットが例外をスローしました。 --->
	System.UnauthorizedAccessException: アクセスが拒否されました。 (HRESULT からの例外: 0x80070005 (E_ACCESSDENIED))
	--- 内部例外スタック トレースの終わり ---
	場所 System.DirectoryServices.DirectoryEntry.Invoke(String methodName, Object[] args)
	場所 ASP.test_aspx.Page_Load(Object sender, EventArgs e)
	場所 c:\inetpub\TestXXXX\Test.aspx:行 29
	--- End --- 2016/08/01 19:24:30

よろしくお願いします。



◇実行/開発環境
	環境は、以下です。
	・実行環境(サーバー)
		OS: Windows Server 2008 R2 Stndard SP1
		アプリケーションサーバー: IIS 7.0
	・開発環境(クライアント)
		OS: Windows10
		IDE: Microsft VisualStudio Express 2015 for Web
		Browser: Internet Explorer11
◇検索キーワード
	記事検索にて、検索したキーワードは、以下です。
	SetPassword
	Active Directory
	DirectoryServices
	UnauthorizedAccessException

引用返信 編集キー/
■80669 / inTopicNo.2)  Re[1]: ASP.Netで実行時エラー0x80070005 (E_AC
□投稿者/ WebSurfer (992回)-(2016/08/01(Mon) 20:54:46)
No80668 (Sasaki さん) に返信

サンプルコードは読んでないのではずれかもしれませんが・・・

> C#コンソールアプリでできたからといって、ASP.Net + IISでもできるとは限らないものなのでしょうか?

コンソールアプリでは、多分あなたが PC にログインしたときのアカウントで実行していて、
ASP.Net + IIS ではワーカープロセスの権限しかないのでうまく行かないということではな
いのですか?

上のレスで何を言っているか分からなければ、どこ分からないか聞いてくださいね。
引用返信 編集キー/
■80670 / inTopicNo.3)  Re[2]: ASP.Netで実行時エラー0x80070005 (E_AC
□投稿者/ Sasaki (9回)-(2016/08/01(Mon) 23:17:33)
> コンソールアプリでは、多分あなたが PC にログインしたときのアカウントで実行していて、
> ASP.Net + IIS ではワーカープロセスの権限しかないのでうまく行かないということではな
> いのですか?
返信ありがとうございます。
Web.configに設定を追加して、PCにログインしたときのアカウントで実行してみましたが、同様の結果でした。
ASP.Net + IISで、実行権限を追加するには、どうするのが一般的なのでしょうか?

引用返信 編集キー/
■80671 / inTopicNo.4)  Re[3]: ASP.Netで実行時エラー0x80070005 (E_AC
□投稿者/ WebSurfer (993回)-(2016/08/01(Mon) 23:26:24)
No80670 (Sasaki さん) に返信

> Web.configに設定を追加して、PCにログインしたときのアカウントで実行してみましたが、同様の結果でした。

偽装したけどダメだったと言っていますか?
引用返信 編集キー/
■80672 / inTopicNo.5)  Re[1]: ASP.Netで実行時エラー0x80070005 (E_AC
□投稿者/ Mira (12回)-(2016/08/02(Tue) 08:44:13)
No80668 (Sasaki さん) に返信

> // ディレクトリサービスの利用
> using(DirectoryEntry directoryEntry = new DirectoryEntry(@"LDAP://dc=xxxx,dc=local")) { // ←ドメインの指定(ドメイン名="xxxx.local")

DirectoryEntryのコンストラクタにはユーザーとパスを指定できますのでそちらにActiveDirectoryのパスワード管理権限のあるユーザーを指定してみるとどうなりますか?

https://msdn.microsoft.com/ja-jp/library/bw8k1as4(v=vs.110).aspx
引用返信 編集キー/
■80673 / inTopicNo.6)  Re[2]: ASP.Netで実行時エラー0x80070005 (E_AC
□投稿者/ Sasaki (10回)-(2016/08/02(Tue) 11:23:48)
ありがとうございます。いま実行環境が手元にないですが、昨日確認したことを記載します。(後ほど改めて再確認します。)

1.偽装について
	IISの設定画面の、[認証アイコン]から偽装を有効にし、
	管理者権限を持っているアカウント(PCにログインしたときのアカウント)を指定しても、
	同様にE_ACCESSDENIEDエラーが発生しました。

	またweb.configファイルに、
	<identity impersonate="true" userName="AdminUserID" password="AdminPassword" />
	を追加しても、同様にE_ACCESSDENIEDエラーが発生しました。

	(実行時にSystem.Security.Principal.WindowsIdentity.GetCurrent().Nameをダンプすることで、
	管理者権限持ちアカウントになっていることは確認できました。)

2.DirectoryServiceのコンストラクタについて
	> using(DirectoryEntry directoryEntry = new DirectoryEntry(@"LDAP://dc=xxxx,dc=local")) {	// ←ドメインの指定(ドメイン名="xxxx.local")
	を、
	using(DirectoryEntry directoryEntry = new DirectoryEntry(@"LDAP://dc=xxxx,dc=local", "AdminUserID", "AdminPassword", AuthenticationTypes.Secure)) {
	としましたが、同様にE_ACCESSDENIEDエラーが発生しました。もしかしてAuthenticationTypes.Secureの指定は不要だったのでしょうか?

	また
	using(DirectoryEntry userEntry = result.GetDirectoryEntry()) {
	を、
	using(DirectoryEntry userEntry = result.GetDirectoryEntry()) {
		using(DirectoryEntry ue = new DirectoryEntry(userEntry.Path, "AdminUserID", "AdminPassword", AuthenticationTypes.Secure)) {
			ue.Invoke("SetPassword", ……
	のように管理者アカウントを追加しなおしたDirectoryEntryを利用しても、E_ACCESSDENIEDエラーでした。

なおWebサイトの構成は、デフォルト(root)のアプリケーションの直下に、アプリケーションを作成ました。
アプリケーションプールを新規作成し、管理者権限で実行するようにしても、同様の箇所で、E_ACCESSDENIEDエラーが発生しました。
他に確認すべきこと、試行できることがございましたら、教えていただけると助かります。

引用返信 編集キー/
■80674 / inTopicNo.7)  Re[3]: ASP.Netで実行時エラー0x80070005 (E_AC
□投稿者/ PANG2 (132回)-(2016/08/02(Tue) 13:13:04)
No80673 (Sasaki さん) に返信
> using(DirectoryEntry userEntry = result.GetDirectoryEntry()) {
> using(DirectoryEntry ue = new DirectoryEntry(userEntry.Path, "AdminUserID", "AdminPassword",


https://msdn.microsoft.com/ja-jp/library/ms180890(v=vs.90).aspx
より

string domainAndUsername = domain + @"\" + username;
DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);

引用返信 編集キー/
■80675 / inTopicNo.8)  Re[4]: ASP.Netで実行時エラー0x80070005 (E_AC
□投稿者/ Sasaki (11回)-(2016/08/02(Tue) 13:19:57)
PANG2さん、ありがとうございます。
管理者アカウントの先頭に、ドメイン名をつけていませんでした。
明日確認した上で、どうなったかお伝えいたします。

> string domainAndUsername = domain + @"\" + username;
> DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);

引用返信 編集キー/
■80676 / inTopicNo.9)  Re[4]: ASP.Netで実行時エラー0x80070005 (E_AC
□投稿者/ なちゃ (124回)-(2016/08/02(Tue) 13:22:14)
こんなんありました。

http://stackoverflow.com/questions/28860601/cannot-set-password-with-directoryentry-invoke-when-user-is-created-in-ad-using
引用返信 編集キー/
■80697 / inTopicNo.10)  Re[5]: ASP.Netで実行時エラー0x80070005 (E_AC
□投稿者/ Sasaki (12回)-(2016/08/03(Wed) 17:45:23)
アドバイスありがとうございます。おかげさまで、解決できました。
教えていただいた、ふたつの方法を実施する必要がありました。以下に、結果をまとめます。

1.DirectoryEntryに指定するUsernameは、ドメイン名を含める
	DirectoryEntryに指定するUsernameには、ドメイン名を追加する必要がありました。
	次のようにに変更しました。AuthenticationTypeは省略しました。

	using(DirectoryEntry userEntry = result.GetDirectoryEntry()) {
		// パスワードのリセット
//		userEntry.AuthenticationType = AuthenticationTypes.Secure;		// ←指定不要でした
		userEntry.Username = @"Domain\AdminUserID";				// ←パスワード変更権限をもっているWindowsアカウントのドメイン名 + @"\" + ユーザーID
		userEntry.Password = @"AdminPassword";					// ←パスワード変更権限をもっているWindowsアカウントのパスワード
		userEntry.Invoke("SetPassword", new object[] { "Password_Xx99!&" });
		userEntry.CommitChanges();
	}

2.DirectoryEntryに指定するUsernameは、AD管理ツールから[制御の委任]を実施し、パスワード変更権限を付与する
	DirectoryEntryに指定するUsernameは、AD管理ツールを利用して、ADを操作するための権限を付与する必要がありました。
	たしかこのAD管理ツールは、クライアントPCにはインストールされていなかったと思います。
	ActiveDirectoryサーバーに直接ログインするか、Microsoftのサイトからダウンロードする必要があったと思います。無料でした。
	権限を付与する手順は以下です。

	(1)AD管理ツールの起動
		Windowsのメニュー[管理ツール]より、[Active Directory ユーザーとコンピューター]を選択します。
	(2)制御の委任
		AD管理ツール左側ペインのドメイン名を右クリックし、[制御の委任]を選択。
	(3)権限の追加
		Wizardが立ち上がるので、対象のWindowsアカウント(もしくは所属しているグループ?)を指定、追加します。
		[ユーザーのパスワードをリセットして次回ログオン時にパスワードの変更を要求する]をチェックします。

これら、ふたつの変更、設定をすることで、ASP.Netからでもパスワードのリセットをすることができるようになりました。
ちなみに、今回の件では、Web.configや偽装の設定は不要でした。CurrentUserは、[IIS APPPOOL\DefaultAppPool]のままです。

ありがとうございました。

引用返信 編集キー/
■80698 / inTopicNo.11)  Re[6]: ASP.Netで実行時エラー0x80070005 (E_AC
□投稿者/ Sasaki (13回)-(2016/08/03(Wed) 17:45:41)
2016/08/03(Wed) 17:48:10 編集(投稿者)

解決済フラグをたてました。
ありがとうございました。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -