如果存在 SQL 相关调用,则 UserPrincipal.FindByIdentity 返回 null,否则返回正确的主体对象
我有这个奇怪的问题。我正在尝试创建一项服务,将数据库中的用户同步到 Active Directory(AD)中电子邮件组中的用户。因此,如果 A、B、C 在数据库中,并且 Active Directory 电子邮件组有 A 和 C; E,我会同步AD。所以我将添加“E”并删除“B”和“B”。 'C'。
为了从数据库获取用户,我执行 SQL 调用。之后,如果我尝试添加用户,我会得到 UserPrincipal.FindByIdentity 为空。这是我贴出的测试代码。
int tries = 0;
List<string> dbUsers = new List<string>();
dbUsers.Add("12345");//test user id's
dbUsers.Add("67891");
int k = 0;
for (k = 0; k < dbUsers.Count; k++)
{
AddUserToGroup(tries, dbUsers[k]);
}
public void AddUserToGroup(int tries, string userid)
{
try
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName, Container, userName, Password);
Principal user = Principal.FindByIdentity(ctx, userid);
string groupName = "TestGroup";
using (ctx)
{
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, groupName);
if (!user.IsMemberOf(group))
{
group.Members.Add(ctx, IdentityType.UserPrincipalName, user.UserPrincipalName);
group.Save();
}
}
}
catch (AppDomainUnloadedException ex)
{
if (tries > 5)
{
throw;
}
tries += 1;
Thread.Sleep(1000);
AddUserToGroup(tries, userid);
}
}
这部分工作完美,我正确地获得了“用户”对象,并且可以成功地将其添加到 AD 电子邮件组。问题是当我使用 SQL 调用从数据库获取 userId 而不是硬编码时。
因此,有问题的代码是:
List<string> dbUsers = GetActiveMembersFromDB('id')
public List<string> GetActiveMembersFromDB(string practiceGroupId)
{
List<string> outpt = new List<string>();
string SQLstring = string.Empty;
string SQL_CONNECTION_STRING = "connectionString";
SQLstring = "SELECT * from dbo.test";//whatever query
using (SqlConnection cn = new SqlConnection(SQL_CONNECTION_STRING))
{
cn.Open();
try
{
SqlCommand cm = new SqlCommand(SQLstring, cn);
using (SqlDataReader dr = cm.ExecuteReader())
{
if (dr.HasRows)
{
while (dr.Read())
{
outpt.Add(dr["userId"].ToString());
}
return outpt;
}
}
}
catch (Exception ex)
{
}
finally
{
if (cn != null)
{
SqlConnection.ClearPool(cn);
cn.Close();
}
}
}
return outpt;
}
因此,在从数据库获取用户后,如果我调用:
int k = 0;
for (k = 0; k < dbUsers.Count; k++)
{
AddUserToGroup(tries, dbUsers[k]);
}
我的“用户”将返回为空。
还有其他人遇到过同样的问题吗? DB调用和AD调用一起有什么问题。我的意思是,我关闭数据库调用中的所有连接,然后尝试访问 Active Directory(AD)。
任何帮助表示赞赏。
谢谢, 迪克沙
I have this weird issue. I am trying to create a service that synchs the users in database to users in Email groups in Active Directory(AD). So if A, B, C are in database and the active directory email group has A & E, I will synch the AD. So I will add 'E' and remove 'B' & 'C'.
To get users from database I execute SQL calls. And after that if I try to add the user I get UserPrincipal.FindByIdentity as null. Here is a test code I have put up.
int tries = 0;
List<string> dbUsers = new List<string>();
dbUsers.Add("12345");//test user id's
dbUsers.Add("67891");
int k = 0;
for (k = 0; k < dbUsers.Count; k++)
{
AddUserToGroup(tries, dbUsers[k]);
}
public void AddUserToGroup(int tries, string userid)
{
try
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName, Container, userName, Password);
Principal user = Principal.FindByIdentity(ctx, userid);
string groupName = "TestGroup";
using (ctx)
{
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, groupName);
if (!user.IsMemberOf(group))
{
group.Members.Add(ctx, IdentityType.UserPrincipalName, user.UserPrincipalName);
group.Save();
}
}
}
catch (AppDomainUnloadedException ex)
{
if (tries > 5)
{
throw;
}
tries += 1;
Thread.Sleep(1000);
AddUserToGroup(tries, userid);
}
}
This piece works perfectly and I get the 'user' object correctly and I can successfully add it to AD email group. Problem is when I have SQL call to get userId's from Database instead of hard coding.
So the code that is problematic is:
List<string> dbUsers = GetActiveMembersFromDB('id')
public List<string> GetActiveMembersFromDB(string practiceGroupId)
{
List<string> outpt = new List<string>();
string SQLstring = string.Empty;
string SQL_CONNECTION_STRING = "connectionString";
SQLstring = "SELECT * from dbo.test";//whatever query
using (SqlConnection cn = new SqlConnection(SQL_CONNECTION_STRING))
{
cn.Open();
try
{
SqlCommand cm = new SqlCommand(SQLstring, cn);
using (SqlDataReader dr = cm.ExecuteReader())
{
if (dr.HasRows)
{
while (dr.Read())
{
outpt.Add(dr["userId"].ToString());
}
return outpt;
}
}
}
catch (Exception ex)
{
}
finally
{
if (cn != null)
{
SqlConnection.ClearPool(cn);
cn.Close();
}
}
}
return outpt;
}
So after fetching users from DB, if I call:
int k = 0;
for (k = 0; k < dbUsers.Count; k++)
{
AddUserToGroup(tries, dbUsers[k]);
}
My 'user' is coming back as null.
Has anyone else encountered the same problem. What's wrong with DB calls and AD calls together. I mean, I close all connections in my db calls and then try to access the Active Directory(AD).
Any help is appreciated.
Thanks,
Deeksha
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

AD和SQL混用应该没有问题。您唯一的耦合是
List
。如果字符串在一种情况下工作,而相同的字符串在另一种情况下不起作用,那么它不应该与获取字符串的方式有任何关系,而是环境或线程上的不同内容,例如安全上下文或类似的内容。我认为您需要将其提炼为显示问题的最小测试用例。
我注意到您的用户名和密码是在给定代码之外定义的 - 您是否检查过并确保没有覆盖它们?
There should be no problem mixing AD and SQL. Your only coupling is
List<string>
. If the strings work in one case and the same string don't work in another, it shouldn't have anything to do with how you got the strings, but something different in the environment or on the thread, like the security context or similar.I think you need to distill it down to the smallest test case which shows the problem.
I notice that your username and password are defined outside of the code given - have you checked and made sure you aren't overwriting them?