2011-07-29 23 views
2

フォーム認証済みのイントラネットでADを照会し、後でユーザーを偽装するためにセッションにWindows IDのコピーを保存しますADエントリー。偽装(長い話)のためにWindows認証を使用することはできません。ASP.NETフォーム認証サイトのユーザーAD情報を更新する偽装

だから、ログインコードは次のとおりです。

[DllImport("advapi32.dll")] 
     public static extern bool LogonUser(String 
      lpszUsername, String lpszDomain, 
      String lpszPassword, int dwLogonType, int 
       dwLogonProvider, out int phToken); 

     public bool LoginWindowsUser(String domain, String username, String pwd, HttpSessionStateBase session) 
     { 

      int ret = 0; 
      int l_token1; 
      bool loggedOn = LogonUser(username, 
       domain, pwd, 
       // Logon type=LOGON32_LOGON_NETWORK_CLEARTEXT. 
      3, 
       // Logon provider=LOGON32_PROVIDER_DEFAULT. 
      0, 
       // User token for specified user is returned 
       //here. 
      out l_token1); 

      if (loggedOn) 
      { 
       IntPtr token2 = new IntPtr(l_token1); 
       var l_Wid = new WindowsIdentity(token2); 


       session["WindowsIdentity"] = l_Wid; 
      } 
      return loggedOn; 
     } 

そしてその後、我々は、ユーザーのAD情報を更新する必要があるときに我々はこれを行う:

public void UpdateUserProperty(string username, string propertyName, string propertyValue) 
     { 
      // Obtain the authenticated user's identity. 
      var winId = (WindowsIdentity) ControllerContext.HttpContext.Session["WindowsIdentity"]; 
      // Start impersonating. 
      using (WindowsImpersonationContext ctx = winId.Impersonate()) 
      { 
       try 
       { 
        var ds = new DirectorySearcher(); 
        int ind = username.IndexOf("\\") + 1; 
        username = username.Substring(ind, username.Length - ind); 

        var filter = "(&(objectCategory=Person)(objectClass=user)"; 

        if (!username.IsNullOrEmpty()) 
        { 
         filter += "(samaccountname=*{0}*)".F(username); 
        } 

        filter += ")"; 

        ds.Filter = filter; 

        foreach (var property in ADUserDetailsDisplay.LoadProperties()) 
        { 
         ds.PropertiesToLoad.Add(property); 
        } 

      ///////////// ERROR OCCURS AFTER NEXT LINE ///////////// 

        var searchResult = ds.FindOne(); 

        var userDirectoryEntry = searchResult.GetDirectoryEntry(); 

        if (propertyValue.IsNullOrEmpty()) 
        { 
         if (userDirectoryEntry.Properties[propertyName].Count > 0) userDirectoryEntry.Properties[propertyName].RemoveAt(0); 
        } 
        else if (userDirectoryEntry.Properties[propertyName].Count == 0) 
        { 
         userDirectoryEntry.Properties[propertyName].Add(propertyValue); 
        } 
        else 
        { 
         userDirectoryEntry.Properties[propertyName][0] = propertyValue; 
        } 
        userDirectoryEntry.CommitChanges(); 


       } 
       catch (Exception ex) 
       { 
        TempData.AddErrorMessage("Unable to update user: " + ex.Message); 
       } 
       finally 
       { 
        // Revert impersonation. 
        if (ctx != null) 
         ctx.Undo(); 
       } 
      } 
      // Back to running under the default ASP.NET process identity. 

     } 

問題は、我々は次のエラーを取得しているということです:

ユーザーを更新できません。操作エラーが発生しました。

誰かが私を解決策に導くことができれば、とても感謝しています。

IIS 7.5 Win2008 R2の使用ASP.NET MVC2

ありがとうございます。

答えて

0

どこに接続しようとしているのか/どこで検索しようとしているのかを示すcontext/searchrootはどこですか?

Ex。あなたがMSDNによると、その後、これを持っていない場合searchrootのためのデフォルト値はnullです

// Bind to the users container. 
DirectoryEntry entry = new DirectoryEntry("LDAP://CN=users,DC=fabrikam,DC=com"); 
// Create a DirectorySearcher object. 
DirectorySearcher mySearcher = new DirectorySearcher(entry); 

... MSDNのリンク:http://msdn.microsoft.com/en-us/library/h9zyssd8.aspx

+0

これは完全な答えではありませんでしたが、私がやり遂げたのは、ユーザーのアカウントに基づいてディレクトリエントリを作成し、それにサーチャーをバインドすることでした。私は偽装ウィンドウのコンテキストを使用して廃止しました。 – Richard

0

当社独自の@dunnryは、ASP.NETの下に偽装して実行されているSystem.DirectoryServicesを取得する手順を取り上げました:

Ryann Dunn can help you here.

0

は、ADへの対処時々PIAがあります。

とにかく、アプリケーションを実行しているアプリケーションプールに設定されているアカウントに、アクティブディレクトリの管理者権限があることを確認して、ユーザーアカウントの変更を実行してください。

+0

それはしませんが、これはポイントです。私はログインしているユーザー(自分のAD情報を変更する特権を持っている人 - 電話やアドレスなどの選択されたフィールド)を偽装しています – Richard

関連する問題