获取用户所属的组列表 [英] Get list of the Groups a User belongs to

查看:73
本文介绍了获取用户所属的组列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何获得用户

所属的本地和域组的列表。

解决方案



在Windows Server 2003域上,您可以通过

构建一个WindowsIdentity,在表单中输入用户名,name @ domain :


WindowsIdentity(String)构造函数
http://msdn2.microsoft.com/en-us/library/td3046fc.aspx


然后你可以访问Groups属性(仅限2.0框架):


" WindowsIdentity.Groups Property"
http://msdn2.microsoft.com/en-us/lib...ty.groups.aspx


如果由于使用的是其他版本而无法使用上述解决方案

e框架或不同的域然后我认为你将不得不诉诸

非托管API,如LogonUser:


LogonUser
http://msdn2.microsoft.com/en- us / library / aa378184.aspx


以上将为您提供用户的令牌,您可以将其传递给以下

功能:


GetTokenInformation
http://msdn2.microsoft.com/en-us/library/aa446671.aspx

指定TOKEN_GROUPS的值为TokenInformationClass参数。


(注意我自己没有使用过这些API)


你必须使用P / Invoke对此,当然:)


-

Dave Sexton


杰夫威廉姆斯 < je *********** @ hardsoft.com.auwrote in message

news:12 ************* @ corp.supernews .com ...


如何获得用户

所属的本地和域组的列表。



" Dave Sexton" < dave @jwa [remove.this] online.comwrote in message

news:uT ************* @ TK2MSFTNGP02.phx.gbl ...


你必须使用P / Invoke,当然:)



System.DirectoryServices将为你做所有这些,以及更多,没有

求助于p / invoke ...


使用系统;

使用System.Collections.Generic;

使用System.DirectoryServices;


public static List< stringGetGroupsForUser(string pstrUser)

{

///< summary>

///获取用户所属的组

///< / summary>

///< param name =" pstrGroup">要评估的ActiveDirectory组< / param>

///< returns> List< psofUser的字符串组< / returns>

DirectorySearcher objDS = null;

SearchResult objSR = null;

DirectoryEntry objUser = null ;

列表< stringlstGroups =新列表< string>();


尝试

{

objDS = new DirectorySearcher(" objectCategory = User");

objDS.Filter ="(SAMAccountName =" + pstrUser +")" ;;

objSR = objDS.FindOne();

objUser = new DirectoryEntry(objSR.Path);


PropertyCollection colProperties = objUser.Properties;

PropertyValueCollection colPropertyValues = colProperties [" memberOf"];

foreach(colPropertyValues中的字符串strGroup)

{

lstGroups.Add(GetSAMAccountName(strGroup).ToLower());

}

返回lstGroups;

}

catch(例外)

{

throw;

}

终于

{

if(objUser!= null)

{

objUser.Close( );

objUser.Dispose();

objUser = null;

}

if(objSR!= null)

{

objSR = null;

}

if(objDS!= null)

{

objDS.Dispose();

objDS = null;

}

}

}


公共静态字符串GetSAMAccountName(stri ng pstrPath)

{

///< summary>

///从给定的LDAP路径获取SAM帐户名

///< / summary>

///< param name =" pstrPath">绑定到< / param>的LDAP路径


DirectoryEntry objADEntry = null;


尝试

{

objADEntry = new DirectoryEntry(" LDAP) ://" + pstrPath);

返回objADEntry.Properties [" SAMAccountName"]。Value.ToString();

}

catch(系统。 Runtime.InteropServices.COMException)

{

返回String.Empty;

}

catch(System.NullReferenceException) )

{

返回String.Empty;

}

catch(例外)

{

throw;

}

终于

{

if( objADEntry!= null)

{

objADEntry.Close();

objADEntry.Dispose();

objADEntry = null;

}

}

}


" Mark Rae" ; < ma ** @ markNOSPAMrae.com写信息

news:OH ************** @ TK2MSFTNGP04.phx.gbl ...
< blockquote class =post_quotes>
" Dave Sexton" < dave @jwa [remove.this] online.comwrote in message

news:uT ************* @ TK2MSFTNGP02.phx.gbl ...


>你必须使用P / Invoke,当然:)



系统.DirectoryServices将为您完成所有这些,以及更多,无需借助系统支付

p / invoke ...


;

使用System.Collections.Generic;

使用System.DirectoryServices;


public static List< stringGetGroupsForUser(string pstrUser)

{

///< summary>

///获取用户所属的组

///< ; / summary>

///< param name =" pstrGroup">要评估的ActiveDirectory组< / param>

///< returns> List< ; psofUser的字符串组< / returns>

DirectorySearcher objDS = null;

SearchResult objSR = null;

DirectoryEntr y objUser = null;

列表< stringlstGroups =新列表< string>();


尝试

{

objDS = new DirectorySearcher(" objectCategory = User");

objDS.Filter ="(SAMAccountName =" + pstrUser +")" ;;

objSR = objDS.FindOne();

objUser = new DirectoryEntry(objSR.Path);


PropertyCollection colProperties = objUser.Properties;

PropertyValueCollection colPropertyValues = colProperties [" memberOf"];

foreach(colPropertyValues中的字符串strGroup)

{

lstGroups.Add(GetSAMAccountName(strGroup).ToLower());

}

返回lstGroups;

}

catch(例外)

{

throw;

}

终于

{

if(objUser!= null)

{

objUser.Close( );

objUser.Dispose();

objUser = null;

}

if(objSR!= null)

{

objSR = null;

}

if(objDS!= null)

{

objDS.Dispose();

objDS = null;

}

}

}


公共静态字符串GetSAMAccountName(字符串pstrPath)

{

///< summary>

///从给定的LDAP路径获取SAM帐户名

///< ; / summary>

///< param name =" pstrPath">绑定到< / param>的LDAP路径

DirectoryEntry objADEntry = null;


尝试

{

objADEntry = new DirectoryEntry(" LDAP://" + pstrPath);

返回objADEntry.Properties [" SAMAccountName"]。Value.ToString();

}

catch(系统。 Runtime.InteropServices.COMException)

{

返回String.Empty;

}

catch(System.NullReferenceException) )

{

返回String.Empty;

}

catch(例外)

{

throw;

}

终于

{

if( objADEntry!= null)

{

objADEntry.Close();

objADEntry.Dispose();

objADEntry = null;

}

}

}



只是几个备注:

您可以通过应用* using *

成语来简化代码并使其更易于阅读和维护,这样,您就可以摆脱Dispose,Close并且完全冗余obj = null

电话。

你的代码只会工作k当调用者在他的域帐户中运行时,如果不是这样的话,你需要明确绑定域或DC,最好使用

FastBind出于性能原因。您也可以使用

GC:// ...绑定到GC(全局目录)以加快查询速度。

另一个需要考虑的问题是绑定用户必须具有查询权限您查询的对象的所有权限,通常所有域成员都拥有此权限,但高度安全

AD可能限制访问某些对象到特殊帐户只要。因此,

用户可以绑定到他的用户对象,但不能绑定到(某些)相关对象。

您还应该尝试重用已经建立了DirectoryEntry对象以进一步对AD进行操作
操作,强制执行adi重新绑定的方式,这可能是一个昂贵的操作,特别是在慢速连接和使用很多时LDAP服务器上的更多资源。

以下代码片段展示了如何通过对每个连续的对象检索使用

GetDirectorEntry()来利用单个绑定。 />

public static List< stringGetGroupsForUser(string userAccount)

{

string rootPath =" LDAP:// {0} / DC = xxx,DC = yyy,DC = zzz" ;;

string accountDomain =" domain" ;; //绑定到域名或dc名称或为空时

登录域

string userAccount = userAccount

rootPath = String.Format(

rootPath


,accountDomain);

string authUser =" xxx\yyyyy" ;; //用于绑定的帐户,这里硬编码,不是
生产安全!

string authPassword =" PASSWORD" ;; //他的密码,这里硬编码,不是制作

安全!


列表< stringlstGroups =新列表< string>();

using(DirectoryEntry root = new DirectoryEntry(rootPath,authUser,authPassword,

AuthenticationTypes.FastBind))

{

using(DirectorySearcher ds = new DirectorySearcher(root))

{

SearchResult sr = null;

ds.Filter ="(SAMAccountName =" + userAccount使用(DirectoryEntry user = sr.GetDirectoryEntry())
{

PropertyCollection pcoll = user.Properties;

PropertyValueCollection memberOf = pcoll [" memberOf"];

foreach(memberOf中的字符串cnGroup)

{

ds.Filter = cnGroup.Substring(0,cnGroup.IndexOf('',''));

sr = ds .FindOne();

使用(DirectoryEntry group = sr.GetDirectoryEntry())

{

lstGroups.Add(group.Pr operties [" SAMAccountName"]。Value.ToString());

}

}

}

}

}

返回lstGroups;

}

....


Willy。


How can I get a list of the Groups both Local and Domain groups a User
belongs to.

解决方案

Hi,

On a Windows Server 2003 domain you can construct a WindowsIdentity by
passing in the user''s name in the form, name@domain:

"WindowsIdentity(String) Constructor"
http://msdn2.microsoft.com/en-us/library/td3046fc.aspx

Then you can access the Groups property (2.0 framework only):

"WindowsIdentity.Groups Property"
http://msdn2.microsoft.com/en-us/lib...ty.groups.aspx

If you can''t use the above solution since you are using a different version
of the framework or a different domain then I think you''ll have to resort to
the unmanaged APIs such as LogonUser:

"LogonUser"
http://msdn2.microsoft.com/en-us/library/aa378184.aspx

The above will get you the User''s token, which you can pass to the following
function:

"GetTokenInformation"
http://msdn2.microsoft.com/en-us/library/aa446671.aspx

Specify the value of TOKEN_GROUPS for the TokenInformationClass argument.

(Note that I haven''t used these APIs myself)

You''ll have to use P/Invoke for this, of course :)

--
Dave Sexton

"Jeff Williams" <je***********@hardsoft.com.auwrote in message
news:12*************@corp.supernews.com...

How can I get a list of the Groups both Local and Domain groups a User
belongs to.



"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:uT*************@TK2MSFTNGP02.phx.gbl...

You''ll have to use P/Invoke for this, of course :)

System.DirectoryServices will do all of this, and much more, for you without
recourse to p/invoke...

using System;
using System.Collections.Generic;
using System.DirectoryServices;

public static List<stringGetGroupsForUser(string pstrUser)
{
/// <summary>
/// Gets the groups a user is a member of
/// </summary>
/// <param name="pstrGroup">ActiveDirectory group to evaluate</param>
/// <returns>List<stringof groups for pstrUser</returns>

DirectorySearcher objDS = null;
SearchResult objSR = null;
DirectoryEntry objUser = null;
List<stringlstGroups = new List<string>();

try
{
objDS = new DirectorySearcher("objectCategory=User");
objDS.Filter = "(SAMAccountName=" + pstrUser + ")";
objSR = objDS.FindOne();
objUser = new DirectoryEntry(objSR.Path);

PropertyCollection colProperties = objUser.Properties;
PropertyValueCollection colPropertyValues = colProperties["memberOf"];
foreach (string strGroup in colPropertyValues)
{
lstGroups.Add(GetSAMAccountName(strGroup).ToLower( ));
}
return lstGroups;
}
catch (Exception)
{
throw;
}
finally
{
if (objUser != null)
{
objUser.Close();
objUser.Dispose();
objUser = null;
}
if (objSR != null)
{
objSR = null;
}
if (objDS != null)
{
objDS.Dispose();
objDS = null;
}
}
}

public static string GetSAMAccountName(string pstrPath)
{
/// <summary>
/// Gets a SAM Account Name from a given LDAP path
/// </summary>
/// <param name="pstrPath">LDAP path to bind to</param>

DirectoryEntry objADEntry = null;

try
{
objADEntry = new DirectoryEntry("LDAP://" + pstrPath);
return objADEntry.Properties["SAMAccountName"].Value.ToString();
}
catch (System.Runtime.InteropServices.COMException)
{
return String.Empty;
}
catch (System.NullReferenceException)
{
return String.Empty;
}
catch (Exception)
{
throw;
}
finally
{
if (objADEntry != null)
{
objADEntry.Close();
objADEntry.Dispose();
objADEntry = null;
}
}
}


"Mark Rae" <ma**@markNOSPAMrae.comwrote in message
news:OH**************@TK2MSFTNGP04.phx.gbl...

"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:uT*************@TK2MSFTNGP02.phx.gbl...

>You''ll have to use P/Invoke for this, of course :)


System.DirectoryServices will do all of this, and much more, for you without recourse to
p/invoke...

using System;
using System.Collections.Generic;
using System.DirectoryServices;

public static List<stringGetGroupsForUser(string pstrUser)
{
/// <summary>
/// Gets the groups a user is a member of
/// </summary>
/// <param name="pstrGroup">ActiveDirectory group to evaluate</param>
/// <returns>List<stringof groups for pstrUser</returns>

DirectorySearcher objDS = null;
SearchResult objSR = null;
DirectoryEntry objUser = null;
List<stringlstGroups = new List<string>();

try
{
objDS = new DirectorySearcher("objectCategory=User");
objDS.Filter = "(SAMAccountName=" + pstrUser + ")";
objSR = objDS.FindOne();
objUser = new DirectoryEntry(objSR.Path);

PropertyCollection colProperties = objUser.Properties;
PropertyValueCollection colPropertyValues = colProperties["memberOf"];
foreach (string strGroup in colPropertyValues)
{
lstGroups.Add(GetSAMAccountName(strGroup).ToLower( ));
}
return lstGroups;
}
catch (Exception)
{
throw;
}
finally
{
if (objUser != null)
{
objUser.Close();
objUser.Dispose();
objUser = null;
}
if (objSR != null)
{
objSR = null;
}
if (objDS != null)
{
objDS.Dispose();
objDS = null;
}
}
}

public static string GetSAMAccountName(string pstrPath)
{
/// <summary>
/// Gets a SAM Account Name from a given LDAP path
/// </summary>
/// <param name="pstrPath">LDAP path to bind to</param>

DirectoryEntry objADEntry = null;

try
{
objADEntry = new DirectoryEntry("LDAP://" + pstrPath);
return objADEntry.Properties["SAMAccountName"].Value.ToString();
}
catch (System.Runtime.InteropServices.COMException)
{
return String.Empty;
}
catch (System.NullReferenceException)
{
return String.Empty;
}
catch (Exception)
{
throw;
}
finally
{
if (objADEntry != null)
{
objADEntry.Close();
objADEntry.Dispose();
objADEntry = null;
}
}
}

Just a few remarks:
You may simplify your code and make it easier to read and maintain by applying the *using*
idiom, this way, you get rid of the Dispose, Close and completely redundant "obj = null"
calls.
Your code will only work when the caller is running in his domain account, when this is not
the case, you need to bind explicitly against the Domain or the DC, and preferably using
FastBind for performance reasons. You may also bind to the GC (the Global Catalog) using
GC://... in order to speed-up the queries.
Another point to consider is that the binding user must have "query" privileges to all of
the objects you query, normally all domain member do have this privilege, but highly secured
AD''s may restrict access to some objects to special accounts only. So it''s possible that a
user can bind to his user object, but not to (some) of the related objects.
You should also try to reuse the already established DirectoryEntry object for further
operations against the AD, the way you do forces adsi to rebind and this can be a costly
operation especially on slow connections and uses a lot more resources at the LDAP server.
The following code snip shows how to take advantage of a single bind by using the
GetDirectorEntry() for each successive object retrieval.

public static List<stringGetGroupsForUser(string userAccount)
{
string rootPath = "LDAP://{0}/DC=xxx,DC=yyy,DC=zzz";
string accountDomain = "domain"; // domain name or dc name or empty when binding to
logon domain
string userAccount = userAccount
rootPath = String.Format(
rootPath

, accountDomain);
string authUser = "xxx\yyyyy"; // account used to bind, here hardcoded, not
production safe!
string authPassword = "PASSWORD"; // his password, here hardcoded, not production
safe!

List<stringlstGroups = new List<string>();
using (DirectoryEntry root = new DirectoryEntry(rootPath, authUser, authPassword,
AuthenticationTypes.FastBind))
{
using (DirectorySearcher ds = new DirectorySearcher(root))
{
SearchResult sr = null;
ds.Filter = "(SAMAccountName=" + userAccount + ")";
sr = ds.FindOne();
using (DirectoryEntry user = sr.GetDirectoryEntry())
{
PropertyCollection pcoll = user.Properties;
PropertyValueCollection memberOf = pcoll["memberOf"];
foreach (string cnGroup in memberOf)
{
ds.Filter = cnGroup.Substring(0, cnGroup.IndexOf('',''));
sr = ds.FindOne();
using (DirectoryEntry group = sr.GetDirectoryEntry())
{
lstGroups.Add(group.Properties["SAMAccountName"].Value.ToString());
}
}
}
}
}
return lstGroups;
}
....

Willy.


这篇关于获取用户所属的组列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆