我们有一个经过身份验证的表单intranet,它为登录查询AD,并在会话中存储windows标识的副本,以便在更新其AD条目时模拟用户。我们不能用windows来模仿(说来话长)。
因此,登录代码是:
[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.
}问题是我们得到了以下错误:
无法更新用户:发生了操作错误.
如果有人能引导我找到解决方案,我将非常感激。
使用IIS7.5 Win2008 R2 ASP.NET MVC2
谢谢。
发布于 2011-07-29 13:31:04
您的上下文/搜索器在哪里,它告诉它您要连接的是谁/您想要搜索的位置?
例如。
// 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,SearchRoot的默认值为null.MSDN:http://msdn.microsoft.com/en-us/library/h9zyssd8.aspx
发布于 2011-07-29 13:11:36
我们自己的@dunnry已经解决了让System.DirectoryServices在ASP.NET下模拟运行的步骤:
瑞恩·邓恩可以帮你。
发布于 2011-07-29 13:20:00
处理AD有时是一个PIA。
无论如何,请确保运行应用程序的应用程序池中的帐户集在活动目录上具有在用户帐户中执行更改的管理权限。
https://stackoverflow.com/questions/6873572
复制相似问题