我正在运行一个ASP.NET 4.0应用程序,它使用用户名(即HttpContext.Current.Request.LogonUserIdentity.Name.ToString())来管理对各种组件的访问。
返回的用户名格式为“abc \ jsmith”,其中“abc”是域名,“jsmith”是用户的登录名。
此应用的部分安全模块访问用户所属的Active Directory组(例如,“Accounting”,“AccountsPayable”,“AdminDepartment”)。我可以使用DirectoryEntry.Properties(即System.DirectoryServices.PropertyCollection“)”sAMAccountName“.Value。
从Active Directory中获取用户名。到目前为止,一切都很好,但我希望能够跨多个域扩展应用程序,这意味着我需要能够在Active Directory中找到域名以及用户的登录名。我可以从PrincipalContext获取“域”值,但它返回“abcdc”,而不是“abc”。我是否可以假设此属性将始终在每个域的末尾返回“dc”(如在“域控制器”中)(在这种情况下,我可以使用属性的子字符串),或者在其他地方我可以获得用户的目前的域名?
答案 0 :(得分:5)
我不清楚的一件事是你在域控制器中给出一个目录条件检索域名的问题。我假设您有一台可以看到多个受信任域的服务器,并且用户可以从任何一个域登录您的应用程序,这样您就不会知道测试角色成员资格所需的域名。
要通过ADGroup成员资格控制对功能的访问,您可以使用
HttpContext.Current.User.IsInRole("appdomain\groupname")
其中User.Identity.Name ==“userdomain \ user”。我不熟悉域信任问题,但这假设您可以将受信任域中的用户添加到您控制的域组中,这样您就不必担心组域位置。
如果您不能,或者每个不同的域名中都有相同的组名,那么您可以这样做吗?
HttpContext.Current.User.IsInRole(userDomainname + "\groupname")
有些观点:
**更新6/8/2011 2:15 PM **
如果我正确理解AD,则用户的域是AD返回的用户对象的组成部分。扩展你的“Bob Newaccountant”的例子......
因此,鉴于以下2个域之间存在信任:
1. "abcdc.com"
CN=Users
CN="Bob NewAccountant"
2. "abc.com"
CN=Users
CN="Local User1"
OU=Applications
OU=MyApplication
CN=ReportReaders (Members: abcdc\BNewAccountant, abc\luser1)
您应该根据以下查询获取用户的信息:
//name parameter = domain
//container parameter = distinguished name
using(var ctx = new PrincipalContext(
ContextType.Domain,
name: "abc.com",
container: "OU=MyApplication,OU=Applications,DC=abc,DC=com",
"abc\serviceaccountname",
"Password1"))
{
var officeGroup = GroupPrincipal.FindByIdentity(ctx,
IdentityType.SamAccountName,
"ReportReaders");
foreach(Principal prin in officeGroup.GetMembers(recursive: true))
{
Console.WriteLine("DistinguishedName: " + prin.DistinguishedName
+ " UPN: " + prin.UserPrincipalName);
}
//Should result in
// DistinguishedName: CN=luser1,CN=Users,DC=abc,DC=com UPN: luser1@abc.com
// DistinguishedName: CN=BNewAccountant,CN=Users,DC=abcdc,DC=com UPN: BNewAccountant@abcdc.com
}
因此,您应该能够通过Active Directory的 distinguishedName 或 userPrincipalName 属性获取用户的域。 (注意:我没有方便的双域设置,所以我目前无法测试上面的代码。)这是否越来越近了?
答案 1 :(得分:4)
以下是WMI查找方法。我给你PowerShell写作,但你可以轻松地将其转换为VBScript或C#
PS C:\> (Get-WmiObject Win32_NTDomain).DomainName
请注意,'pre windows 2000 domain'的Domain部分可以与用户Principal Name(user @ domain)用于登录Active Directory的完全不同。 DOMAIN是主域控制器名称或Netbios域名。 DOMAIN是在域创建期间创建的,默认情况下它是DNS名称的一部分,但在域创建期间可以完全更改。
您可以使用nETBIOSName属性找到它:
ldifde -f netbios.ldf -d "CN=Partitions,CN=Configuration,DC=your-DNS-Name" -r "(netbiosname=*)"
被修改
这是CSharp代码
ManagementObjectSearcher domainInfos1 = new ManagementObjectSearcher("select * from WIN32_NTDomain");
foreach (ManagementObject domainInfo in domainInfos1.Get())
{
Console.WriteLine("Name : {0}", domainInfo.GetPropertyValue("Name"));
Console.WriteLine("Computer/domain : {0}", domainInfo.GetPropertyValue("Caption"));
Console.WriteLine("Domain name : {0}", domainInfo.GetPropertyValue("DomainName"));
Console.WriteLine("Status : {0}", domainInfo.GetPropertyValue("Status"));
}
答案 2 :(得分:1)
DC代表域组件。使用Active Directory进行编程的看似不错的概述是here。那里有一点很多可以在这里做一个像样的复制和粘贴,但我确实找到了可以帮助你的following:
domainname=inputbox("Enter DNS Domain Name" & vbcrlf & "(Leave blank for current domain):")
username=inputbox("Enter username:")
IF domainname = "" THEN
SET objRoot = GETOBJECT("LDAP://RootDSE")
domainname = objRoot.GET("defaultNamingContext")
END IF
IF username <> "" THEN
wscript.echo finduser(username,domainname)
END IF
FUNCTION FindUser(BYVAL UserName, BYVAL Domain)
ON ERROR RESUME NEXT
SET cn = CREATEOBJECT("ADODB.Connection")
SET cmd = CREATEOBJECT("ADODB.Command")
SET rs = CREATEOBJECT("ADODB.Recordset")
cn.open "Provider=ADsDSOObject;"
cmd.activeconnection=cn
cmd.commandtext="SELECT ADsPath FROM 'LDAP://" & Domain & _
"' WHERE sAMAccountName = '" & UserName & "'"
SET rs = cmd.EXECUTE
IF err<>0 THEN
FindUser="Error connecting to Active Directory Database:" & err.description
ELSE
IF NOT rs.BOF AND NOT rs.EOF THEN
rs.MoveFirst
FindUser = rs(0)
ELSE
FindUser = "Not Found"
END IF
END IF
cn.close
END FUNCTION
答案 3 :(得分:0)
您可以获得用户“userprincipalname”。它看起来像一个电子邮件地址,但实际上是samaccountname + @ + domain.name。需要注意的一点是,Active Directory域看起来像是互联网域名,但netbios域名(示例中的“abc”)却没有。
如果您抓住UPN,我相信它将始终包含虚线域名。