如何在 .NET Core 中获取 defaultNamingContext?
How to get the defaultNamingContext in .NET Core?
我正尝试在 .NET Core 中执行 ActiveDirectory/LDAP-Authentication。
但是.NET Core (NetStandard 1.6).
中没有System.DirectoryServices
因此,我使用 Novell.Directory.Ldap,只要您知道 rootDSE,它就可以正常工作。
通常,我会像这样获取 ActiveDirectory RootDSE-defaultNamingContext:
public static string GetRootDSE()
{
DirectoryEntry rootDSE = new DirectoryEntry("LDAP://rootDSE");
string defaultNamingContext = rootDSE.Properties["defaultNamingContext"].Value;
return defaultNamingContext:
}
但是,由于没有 System.DirectoryServices,我不能那样做。
Novell.Directory.Ldap 似乎没有相应的功能,或者至少我找不到它。
现在,例如在 VBScript 中,您可以获得这样的 defaultNamingContext:
Set objRootDSE = GetObject("LDAP://rootDSE")
strADsPath = "LDAP://" & objRootDSE.Get("defaultNamingContext")
Set objDomain = GetObject(strADsPath)
所以我尝试在 C# 中使用相同的 COM 对象(因为 .NET Core 没有 VB.NET,我无法调用 VB.NET 运行时)。
这是我到目前为止设法得到的:
[System.Runtime.InteropServices.DllImport("Activeds", ExactSpelling = true,
EntryPoint = "ADsGetObject",
CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
public static extern int ADsGetObject(string path
, [System.Runtime.InteropServices.In, System.Runtime.InteropServices.Out] ref System.Guid iid
, [System.Runtime.InteropServices.Out, System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Interface)] out object ppObject
);
public static void Test()
{
dynamic ppObject;
// System.Guid IID_IDirectorySearch = new System.Guid("{ 0x109BA8EC, 0x92F0, 0x11D0, { 0xA7, 0x90, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0xA8 } }");
// System.Guid IID_IADsContainer = new System.Guid("{ 0x001677D0, 0xFD16, 0x11CE, { 0xAB, 0xC4, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53 } }");
System.Guid IID_IADs = new System.Guid("{ 0xFD8256D0, 0xFD15, 0x11CE, { 0xAB, 0xC4, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53 } }");
ADsGetObject("LDAP://rootDSE", ref IID_IADs, out ppObject);
System.Console.WriteLine(ppObject);
object objDSE;
// System.IntPtr objDSE;
// https://msdn.microsoft.com/en-us/library/aa705950(v=vs.85).aspx
// https://msdn.microsoft.com/en-us/library/aa746347(v=vs.85).aspx
// HRESULT Get( [in] BSTR bstrName, [out] VARIANT *pvProp);
// ppObject.Get("defaultNamingContext", out objDSE);
System.IntPtr bstr = System.Runtime.InteropServices.
Marshal.StringToBSTR("defaultNamingContext");
ppObject.Get(bstr, out objDSE);
System.Console.WriteLine(objDSE);
}
我得到了 COM 对象 ("ppObject"),在我调用 ppObject 上的 Get 之前它似乎工作正常。
我得到 "Not Implemented-Exception: Method or process is not implemented."
我做错了什么?
此外,如果有人有更好的方法在 .NET Core 中获取 RootDSE,那么我洗耳恭听。
PS:
我知道这仅适用于 Windows - 我只是将其设置为在 Linux 上手动配置。
啊,没关系,我得到答案了:
如您所见here,您可以运行
nslookup -type=srv _ldap._tcp.DOMAINNAME
以获得想要的结果。
所以当你 运行
nslookup -type=srv _ldap._tcp.YourDomain.local
,这意味着您查询默认 DNS 以获取执行机器域的 ldap-server 记录,并使用该结果。
您可以使用任何支持 .NET Core 的 DNS 库(例如 ArSoft)来做到这一点。
public static void Test4()
{
System.Net.NetworkInformation.IPGlobalProperties ipgp =
System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties();
// IDnsResolver resolver = new RecursiveDnsResolver(); // Warning: Doesn't work
IDnsResolver resolver = new DnsStubResolver();
List<SrvRecord> srvRecords = resolver.Resolve<SrvRecord>("_ldap._tcp." + ipgp.DomainName, RecordType.Srv);
foreach (SrvRecord thisRecord in srvRecords)
{
// System.Console.WriteLine(thisRecord.Name);
System.Console.WriteLine(thisRecord.Target);
System.Console.WriteLine(thisRecord.Port);
// Note: OR LDAPS:// - but Novell doesn't want these parts anyway
string url = "LDAP://" + thisRecord.Target + ":" + thisRecord.Port;
System.Console.WriteLine(url);
} // Next thisRecord
}
我正尝试在 .NET Core 中执行 ActiveDirectory/LDAP-Authentication。
但是.NET Core (NetStandard 1.6).
中没有System.DirectoryServices
因此,我使用 Novell.Directory.Ldap,只要您知道 rootDSE,它就可以正常工作。
通常,我会像这样获取 ActiveDirectory RootDSE-defaultNamingContext:
public static string GetRootDSE()
{
DirectoryEntry rootDSE = new DirectoryEntry("LDAP://rootDSE");
string defaultNamingContext = rootDSE.Properties["defaultNamingContext"].Value;
return defaultNamingContext:
}
但是,由于没有 System.DirectoryServices,我不能那样做。
Novell.Directory.Ldap 似乎没有相应的功能,或者至少我找不到它。
现在,例如在 VBScript 中,您可以获得这样的 defaultNamingContext:
Set objRootDSE = GetObject("LDAP://rootDSE")
strADsPath = "LDAP://" & objRootDSE.Get("defaultNamingContext")
Set objDomain = GetObject(strADsPath)
所以我尝试在 C# 中使用相同的 COM 对象(因为 .NET Core 没有 VB.NET,我无法调用 VB.NET 运行时)。
这是我到目前为止设法得到的:
[System.Runtime.InteropServices.DllImport("Activeds", ExactSpelling = true,
EntryPoint = "ADsGetObject",
CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
public static extern int ADsGetObject(string path
, [System.Runtime.InteropServices.In, System.Runtime.InteropServices.Out] ref System.Guid iid
, [System.Runtime.InteropServices.Out, System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Interface)] out object ppObject
);
public static void Test()
{
dynamic ppObject;
// System.Guid IID_IDirectorySearch = new System.Guid("{ 0x109BA8EC, 0x92F0, 0x11D0, { 0xA7, 0x90, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0xA8 } }");
// System.Guid IID_IADsContainer = new System.Guid("{ 0x001677D0, 0xFD16, 0x11CE, { 0xAB, 0xC4, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53 } }");
System.Guid IID_IADs = new System.Guid("{ 0xFD8256D0, 0xFD15, 0x11CE, { 0xAB, 0xC4, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53 } }");
ADsGetObject("LDAP://rootDSE", ref IID_IADs, out ppObject);
System.Console.WriteLine(ppObject);
object objDSE;
// System.IntPtr objDSE;
// https://msdn.microsoft.com/en-us/library/aa705950(v=vs.85).aspx
// https://msdn.microsoft.com/en-us/library/aa746347(v=vs.85).aspx
// HRESULT Get( [in] BSTR bstrName, [out] VARIANT *pvProp);
// ppObject.Get("defaultNamingContext", out objDSE);
System.IntPtr bstr = System.Runtime.InteropServices.
Marshal.StringToBSTR("defaultNamingContext");
ppObject.Get(bstr, out objDSE);
System.Console.WriteLine(objDSE);
}
我得到了 COM 对象 ("ppObject"),在我调用 ppObject 上的 Get 之前它似乎工作正常。
我得到 "Not Implemented-Exception: Method or process is not implemented."
我做错了什么?
此外,如果有人有更好的方法在 .NET Core 中获取 RootDSE,那么我洗耳恭听。
PS:
我知道这仅适用于 Windows - 我只是将其设置为在 Linux 上手动配置。
啊,没关系,我得到答案了:
如您所见here,您可以运行
nslookup -type=srv _ldap._tcp.DOMAINNAME
以获得想要的结果。
所以当你 运行
nslookup -type=srv _ldap._tcp.YourDomain.local
,这意味着您查询默认 DNS 以获取执行机器域的 ldap-server 记录,并使用该结果。
您可以使用任何支持 .NET Core 的 DNS 库(例如 ArSoft)来做到这一点。
public static void Test4()
{
System.Net.NetworkInformation.IPGlobalProperties ipgp =
System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties();
// IDnsResolver resolver = new RecursiveDnsResolver(); // Warning: Doesn't work
IDnsResolver resolver = new DnsStubResolver();
List<SrvRecord> srvRecords = resolver.Resolve<SrvRecord>("_ldap._tcp." + ipgp.DomainName, RecordType.Srv);
foreach (SrvRecord thisRecord in srvRecords)
{
// System.Console.WriteLine(thisRecord.Name);
System.Console.WriteLine(thisRecord.Target);
System.Console.WriteLine(thisRecord.Port);
// Note: OR LDAPS:// - but Novell doesn't want these parts anyway
string url = "LDAP://" + thisRecord.Target + ":" + thisRecord.Port;
System.Console.WriteLine(url);
} // Next thisRecord
}