2011-07-29 8 views
2

우리는 양식을 인증 할 인트라넷을 사용하여 AD를 쿼리하고 세션에 Windows ID의 복사본을 저장하여 나중에 업데이트 할 때 사용자를 가장합니다 광고 항목. 명의 도용 (긴 기사) 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

검색 대상/연결 대상을 알려주는 컨텍스트/검색 루트는 어디에 있습니까?

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

그것은하지 않습니다,하지만이 지점입니다. 로그인 한 사용자 (자신의 광고 정보를 변경할 수있는 권한이있는 사용자 - 전화 및 주소와 같은 선택된 필드)를 가장합니다. – Richard

관련 문제