C#/LDAP如何查询Active Directory临时组成员的剩余TTL时间
Active Directory临时组成员TTL获取方案(C#实现)
方案1:基于DirectoryEntry实现
查询临时成员TTL需要开启LDAP扩展控制1.2.840.113556.1.4.2309(LDAP_SERVER_LINK_TTL_EXTENDED_OID),开启后返回的member属性会携带TTL前缀,示例代码如下:
using System.DirectoryServices; using System.Text.RegularExpressions; // 替换为目标组的完整DN string groupDn = "CN=mytest,OU=Groups,DC=test,DC=local"; DirectorySearcher searcher = new DirectorySearcher( new DirectoryEntry($"LDAP://{groupDn}"), "(objectClass=group)", new string[] { "member" }, SearchScope.Base ); // 添加Link TTL扩展控制,要求AD返回成员的剩余TTL var ttlControl = new DirectoryControl("1.2.840.113556.1.4.2309", null, true, true); searcher.Controls.Add(ttlControl); searcher.PropertiesToLoad.Add("member"); SearchResult result = searcher.FindOne(); if (result != null && result.Properties.Contains("member")) { // 匹配TTL前缀的正则 Regex ttlRegex = new Regex(@"^<TTL=(\d+)>,", RegexOptions.IgnoreCase); foreach (string memberEntry in result.Properties["member"]) { Match match = ttlRegex.Match(memberEntry); if (match.Success) { // 提取TTL秒数和用户DN int ttlSeconds = int.Parse(match.Groups[1].Value); string userDn = memberEntry.Substring(match.Length); Console.WriteLine($"用户DN:{userDn},剩余有效时长:{ttlSeconds}秒"); } else { Console.WriteLine($"永久成员DN:{memberEntry}"); } } }
方案2:基于GroupPrincipal实现
GroupPrincipal底层绑定的是DirectoryEntry对象,可先获取底层实例再复用上述查询逻辑,示例代码如下:
using System.DirectoryServices.AccountManagement; using System.DirectoryServices; using System.Text.RegularExpressions; // 替换为实际域名 using (PrincipalContext context = new PrincipalContext(ContextType.Domain, "test.local")) { // 替换为目标组名称 GroupPrincipal group = GroupPrincipal.FindByIdentity(context, "mytest"); if (group != null) { // 获取GroupPrincipal底层的DirectoryEntry对象 DirectoryEntry groupDe = (DirectoryEntry)group.GetUnderlyingObject(); DirectorySearcher searcher = new DirectorySearcher( groupDe, "(objectClass=group)", new string[] { "member" }, SearchScope.Base ); // 添加TTL扩展控制 var ttlControl = new DirectoryControl("1.2.840.113556.1.4.2309", null, true, true); searcher.Controls.Add(ttlControl); searcher.PropertiesToLoad.Add("member"); SearchResult result = searcher.FindOne(); // 后续解析逻辑和方案1完全一致 Regex ttlRegex = new Regex(@"^<TTL=(\d+)>,", RegexOptions.IgnoreCase); foreach (string memberEntry in result.Properties["member"]) { Match match = ttlRegex.Match(memberEntry); if (match.Success) { int ttlSeconds = int.Parse(match.Groups[1].Value); string userDn = memberEntry.Substring(match.Length); Console.WriteLine($"用户DN:{userDn},剩余有效时长:{ttlSeconds}秒"); } } group.Dispose(); } }
注意事项
- AD林功能级别需为Windows Server 2012及以上,否则不支持临时组成员特性
- 查询身份需拥有目标组的成员属性读取权限
- TTL返回值为剩余有效秒数,到期后成员会被自动从组中移除
内容的提问来源于stack exchange,提问作者soniclord
相关产品推荐
相关产品推荐

