应用程序创建的 AD 用户未正确解析为 upn 后缀
AD User created by application isn't properly resolving to a upn suffix
我正在编写一些以编程方式创建 AD 用户的代码(将被拉入 MS DYnamics CRM 2013 环境),并且该代码有一个奇怪的问题。我有一个在我们的 AD 结构上创建的 UPN 列表,但出于某种原因,我的 AD 用户没有解析它们。
所以,我有一个包含 example.com 的 UPN 后缀列表。我将用户名设置为 first.last@example.com,它不允许我使用它来登录 CRM。当我检查 AD 条目时,我可以看到它正确地将登录名分配给了 first.last@example.com,但是 @example.com 在列表中出现了两次,该条目实际上是创建和这个新的。所以它没有认识到 @example.com 是一个预先存在的 UPN 后缀,我不能使用 first.last@example.com 来登录 CRM,我必须使用这个例子.local\first.最后。我希望这是有道理的。非常感谢。
那么我如何告诉 AD 记录在登录时使用预先存在的 UPN 而不是...做它正在做的任何事情?这是我的代码:
try
{
string connectionPrefix = "LDAP://" + ldapPath;// ldapPart;// ldapPath
var adminUsername = ConfigurationHelper.GetConfigSettingByName(orgservice,
"ADPasswordReset.AdminUsername", unsecureConfig, secureConfig);
var adminPassword = ConfigurationHelper.GetConfigSettingByName(orgservice,
"ADPasswordReset.AdminPassword", unsecureConfig, secureConfig);
if (CheckIfUserExists(getSAMNameFromUserName(userName), trace) == true)
{
throw new Exception("A User with that name already exists.");
}
DirectoryEntry dirEntry = new DirectoryEntry(connectionPrefix, adminUsername, adminPassword, AuthenticationTypes.Secure);
DirectoryEntry newUser;
string cn = firstName + " " + lastName;
newUser = dirEntry.Children.Add("CN=" + cn, "user"); //display name - This is the "Display" name that shows up on the AD list.
newUser.Properties["displayName"].Value = cn;
newUser.Properties["samAccountName"].Value = getSAMNameFromUserName(userName);//userName;
newUser.Properties["userPrincipalName"].Value = checkUserName(userName);
newUser.Properties["givenName"].Value = firstName; //Firstname
newUser.Properties["sn"].Value = lastName; //Lastname? -Surname
newUser.Properties["LockOutTime"].Value = 0; //unlock account. Set this to 0 to unlock the account.
newUser.CommitChanges();
oGUID = newUser.Guid.ToString();
//Must be handled after the previous stuff. Unsure why.
newUser.Invoke("SetPassword", new object[] { userPassword });
newUser.CommitChanges();
//For some reason, can't be handled before the password is set?
newUser.Properties["userAccountControl"].Value = 0x0200; //0x0200
newUser.CommitChanges();
dirEntry.Close();
newUser.Close();
}
public static string checkUserName(string userName)
{
if (!userName.Contains("@"))
{
return userName + "@example.local";
}
return userName;
}
public static string getSAMNameFromUserName(string domainUserName)
{
int stop;
string s = domainUserName;
if (s.Contains("@"))
{
stop = s.IndexOf("@");
return (stop > -1) ? s.Substring(0, stop) : string.Empty;
}
return domainUserName;// string.Empty;
}
在您的代码中,您将 UPN 设置为 example.local
而不是 example.com
:
public static string checkUserName(string userName)
{
if (!userName.Contains("@"))
{
return userName + "@example.local";
}
return userName;
}
即使域配置了多个可能的后缀,一个用户也只能有一个 UPN。如果您希望 username@example.com
解析,用户必须将 example.com
设置为后缀。
感谢所有花时间提供帮助的人。
空格。哎呀,空格。
对于以后遇到此线程的任何人来说,问题是在 AD 创建过程中,某些东西在我的用户名和域中附加了空格。因此,它不是 "example.com",而是将域保存为 "example.com "(注意末尾的空格吗?)。我 .Trim()' 了一切,它似乎工作得很好。 :)
我的新代码变为:
public static string checkUserName(string userName)
{
if (!userName.Contains("@"))
{
return userName.Trim() + "@domain.local".Trim();
}
return userName.Trim();
}
try
{
string connectionPrefix = "LDAP://" + ldapPath;// ldapPart;// ldapPath
var adminUserName = GetAdminUserName(orgservice, unsecureConfig, secureConfig);
var adminPassword = GetAdminPassword(orgservice, unsecureConfig, secureConfig);
if (CheckIfUserExists(getSAMNameFromUserName(userName), trace) == true)
{
trace.Trace("About to handle success. A User already exists: " + getSAMNameFromUserName(userName));
trace.HandleSuccess();
throw new Exception("User " + getSAMNameFromUserName(userName) + " already exists.");
}
DirectoryEntry dirEntry = new DirectoryEntry(connectionPrefix, adminUserName, adminPassword, AuthenticationTypes.Secure);
DirectoryEntry newUser;
string cn = firstName.Trim() + " " + lastName.Trim();
newUser = dirEntry.Children.Add("CN=" + cn, "user"); //display name - This is the "Display" name that shows up on the AD list.
newUser.Properties["displayName"].Value = cn;
newUser.Properties["samAccountName"].Value = getSAMNameFromUserName(userName).Trim();
newUser.Properties["userPrincipalName"].Value = checkUserName(userName).Trim();
newUser.Properties["givenName"].Value = firstName.Trim(); //Firstname
newUser.Properties["sn"].Value = lastName.Trim(); //Lastname? -Surname
//newUser.Properties["LockOutTime"].Value = 0; //unlock account. Set this to 0 to unlock the account.
newUser.CommitChanges();
oGUID = newUser.Guid.ToString();
//Must be handled after the previous stuff. Unsure why.
newUser.Invoke("SetPassword", new object[] { userPassword });
newUser.CommitChanges();
//For some reason, can't be handled before the password is set?
newUser.Properties["userAccountControl"].Value = 0x10200; //0x0200
newUser.CommitChanges();
//
newUser.Close();
dirEntry.Close();
//newUser.Close(); //Close user first, then dirEntry because of the heirarchy call?
}
catch (System.DirectoryServices.DirectoryServicesCOMException E)
{
System.DirectoryServices.DirectoryServicesCOMException newE = new System.DirectoryServices.DirectoryServicesCOMException(E.Message);
//DoSomethingwith --> E.Message.ToString();
throw newE;
}
我正在编写一些以编程方式创建 AD 用户的代码(将被拉入 MS DYnamics CRM 2013 环境),并且该代码有一个奇怪的问题。我有一个在我们的 AD 结构上创建的 UPN 列表,但出于某种原因,我的 AD 用户没有解析它们。
所以,我有一个包含 example.com 的 UPN 后缀列表。我将用户名设置为 first.last@example.com,它不允许我使用它来登录 CRM。当我检查 AD 条目时,我可以看到它正确地将登录名分配给了 first.last@example.com,但是 @example.com 在列表中出现了两次,该条目实际上是创建和这个新的。所以它没有认识到 @example.com 是一个预先存在的 UPN 后缀,我不能使用 first.last@example.com 来登录 CRM,我必须使用这个例子.local\first.最后。我希望这是有道理的。非常感谢。
那么我如何告诉 AD 记录在登录时使用预先存在的 UPN 而不是...做它正在做的任何事情?这是我的代码:
try
{
string connectionPrefix = "LDAP://" + ldapPath;// ldapPart;// ldapPath
var adminUsername = ConfigurationHelper.GetConfigSettingByName(orgservice,
"ADPasswordReset.AdminUsername", unsecureConfig, secureConfig);
var adminPassword = ConfigurationHelper.GetConfigSettingByName(orgservice,
"ADPasswordReset.AdminPassword", unsecureConfig, secureConfig);
if (CheckIfUserExists(getSAMNameFromUserName(userName), trace) == true)
{
throw new Exception("A User with that name already exists.");
}
DirectoryEntry dirEntry = new DirectoryEntry(connectionPrefix, adminUsername, adminPassword, AuthenticationTypes.Secure);
DirectoryEntry newUser;
string cn = firstName + " " + lastName;
newUser = dirEntry.Children.Add("CN=" + cn, "user"); //display name - This is the "Display" name that shows up on the AD list.
newUser.Properties["displayName"].Value = cn;
newUser.Properties["samAccountName"].Value = getSAMNameFromUserName(userName);//userName;
newUser.Properties["userPrincipalName"].Value = checkUserName(userName);
newUser.Properties["givenName"].Value = firstName; //Firstname
newUser.Properties["sn"].Value = lastName; //Lastname? -Surname
newUser.Properties["LockOutTime"].Value = 0; //unlock account. Set this to 0 to unlock the account.
newUser.CommitChanges();
oGUID = newUser.Guid.ToString();
//Must be handled after the previous stuff. Unsure why.
newUser.Invoke("SetPassword", new object[] { userPassword });
newUser.CommitChanges();
//For some reason, can't be handled before the password is set?
newUser.Properties["userAccountControl"].Value = 0x0200; //0x0200
newUser.CommitChanges();
dirEntry.Close();
newUser.Close();
}
public static string checkUserName(string userName)
{
if (!userName.Contains("@"))
{
return userName + "@example.local";
}
return userName;
}
public static string getSAMNameFromUserName(string domainUserName)
{
int stop;
string s = domainUserName;
if (s.Contains("@"))
{
stop = s.IndexOf("@");
return (stop > -1) ? s.Substring(0, stop) : string.Empty;
}
return domainUserName;// string.Empty;
}
在您的代码中,您将 UPN 设置为 example.local
而不是 example.com
:
public static string checkUserName(string userName)
{
if (!userName.Contains("@"))
{
return userName + "@example.local";
}
return userName;
}
即使域配置了多个可能的后缀,一个用户也只能有一个 UPN。如果您希望 username@example.com
解析,用户必须将 example.com
设置为后缀。
感谢所有花时间提供帮助的人。
空格。哎呀,空格。
对于以后遇到此线程的任何人来说,问题是在 AD 创建过程中,某些东西在我的用户名和域中附加了空格。因此,它不是 "example.com",而是将域保存为 "example.com "(注意末尾的空格吗?)。我 .Trim()' 了一切,它似乎工作得很好。 :)
我的新代码变为:
public static string checkUserName(string userName)
{
if (!userName.Contains("@"))
{
return userName.Trim() + "@domain.local".Trim();
}
return userName.Trim();
}
try
{
string connectionPrefix = "LDAP://" + ldapPath;// ldapPart;// ldapPath
var adminUserName = GetAdminUserName(orgservice, unsecureConfig, secureConfig);
var adminPassword = GetAdminPassword(orgservice, unsecureConfig, secureConfig);
if (CheckIfUserExists(getSAMNameFromUserName(userName), trace) == true)
{
trace.Trace("About to handle success. A User already exists: " + getSAMNameFromUserName(userName));
trace.HandleSuccess();
throw new Exception("User " + getSAMNameFromUserName(userName) + " already exists.");
}
DirectoryEntry dirEntry = new DirectoryEntry(connectionPrefix, adminUserName, adminPassword, AuthenticationTypes.Secure);
DirectoryEntry newUser;
string cn = firstName.Trim() + " " + lastName.Trim();
newUser = dirEntry.Children.Add("CN=" + cn, "user"); //display name - This is the "Display" name that shows up on the AD list.
newUser.Properties["displayName"].Value = cn;
newUser.Properties["samAccountName"].Value = getSAMNameFromUserName(userName).Trim();
newUser.Properties["userPrincipalName"].Value = checkUserName(userName).Trim();
newUser.Properties["givenName"].Value = firstName.Trim(); //Firstname
newUser.Properties["sn"].Value = lastName.Trim(); //Lastname? -Surname
//newUser.Properties["LockOutTime"].Value = 0; //unlock account. Set this to 0 to unlock the account.
newUser.CommitChanges();
oGUID = newUser.Guid.ToString();
//Must be handled after the previous stuff. Unsure why.
newUser.Invoke("SetPassword", new object[] { userPassword });
newUser.CommitChanges();
//For some reason, can't be handled before the password is set?
newUser.Properties["userAccountControl"].Value = 0x10200; //0x0200
newUser.CommitChanges();
//
newUser.Close();
dirEntry.Close();
//newUser.Close(); //Close user first, then dirEntry because of the heirarchy call?
}
catch (System.DirectoryServices.DirectoryServicesCOMException E)
{
System.DirectoryServices.DirectoryServicesCOMException newE = new System.DirectoryServices.DirectoryServicesCOMException(E.Message);
//DoSomethingwith --> E.Message.ToString();
throw newE;
}