惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

W
WeLiveSecurity
博客园 - 【当耐特】
Microsoft Azure Blog
Microsoft Azure Blog
WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
Cloudbric
Cloudbric
The Register - Security
The Register - Security
小众软件
小众软件
PCI Perspectives
PCI Perspectives
G
Google Developers Blog
AI
AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Google DeepMind News
Google DeepMind News
Google DeepMind News
Google DeepMind News
宝玉的分享
宝玉的分享
Recent Commits to openclaw:main
Recent Commits to openclaw:main
量子位
TaoSecurity Blog
TaoSecurity Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
F
Full Disclosure
N
Netflix TechBlog - Medium
博客园_首页
Last Week in AI
Last Week in AI
A
Arctic Wolf
B
Blog RSS Feed
J
Java Code Geeks
C
Cybersecurity and Infrastructure Security Agency CISA
I
InfoQ
aimingoo的专栏
aimingoo的专栏
云风的 BLOG
云风的 BLOG
NISL@THU
NISL@THU
MyScale Blog
MyScale Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Jina AI
Jina AI
有赞技术团队
有赞技术团队
S
Schneier on Security
L
Lohrmann on Cybersecurity
P
Privacy & Cybersecurity Law Blog
T
Threat Research - Cisco Blogs
P
Palo Alto Networks Blog
S
Security @ Cisco Blogs
Security Archives - TechRepublic
Security Archives - TechRepublic
Security Latest
Security Latest
Vercel News
Vercel News
博客园 - 司徒正美
Webroot Blog
Webroot Blog
Hacker News: Ask HN
Hacker News: Ask HN
A
About on SuperTechFans

博客园 - Flier Lu

[草稿] 自动下载完整的.NET源代码 Atlas 实现机制浅析 [3] Atlas 实现机制浅析 [2] Atlas 实现机制浅析 [1] [草稿] Managed COM Apartment - ExecutionContext [1] ASP.NET 2.0 异步页面原理浅析 [1] 也评《应用框架的设计与实现——.NET平台》 CLR 调试支持机制原理浅析 [1] 整体结构 [草稿] 咬文嚼字之 Java 版 关注企业级服务自身的可管理性 享受 .NET 时代的 COM+ 开发 感受 COM+ 事务性 在 CLR 1.1 中获取 IL 函数体信息 GDS [1] 使用Google桌面搜索构建企业搜索方案 基于透明代理的内部类访问抽象 [2] 自动类型转换与封装 基于透明代理的内部类访问抽象 [1] 类型与调用的封装 [TIPS] 正确判断当前用户角色 使用 FishEye 直观了解 CVS 情况 用WinDbg探索CLR世界 [10] 透明代理实现原理浅析 - 静态结构
在 .NET 中获取 AD 上帐号密码过期时间
Flier Lu · 2004-10-21 · via 博客园 - Flier Lu

原文:http://www.blogcn.com/User8/flier_lu/blog/4371854.html

    .NET Framework 提供了 System.DirectoryServices 名字空间用于操作 AD 等支持 LDAP 接口的服务器,通过这组类我们能够很容易实现通过 AD 验证用户帐号,以及向 AD 查询域用户及其所在组的信息,是在 Web 应用中集成 AD 以实现企业单点登陆的重要手段之一。
    纯朴的狗熊在其 blog 上有一系列非常出色的文章介绍了这方面的基本知识

    活动目录.NET编程Tips
    使用System.DirectoryServices.Protocols实现对AD的简单操作
    ADHelper 活动目录用户操作类

    虽然他给出的那个例子代码并不完整,但为后来者提供了很好的基础。

    为了让笔者所在公司的基于 SharePoint 的内网门户能够提供一些方便的小功能,如查询自己帐号的密码过期时间等等,笔者对其封装代码做了一些修改,定义了 AdServer/AdGroup/AdUser 分别用于对 AD 服务器/组/用户的封装,让关系更加清晰。回头等封装代码稳定了,再写篇文章详细介绍。

    其中碰到一个讨厌的问题是如何从 AD 获取当前帐号的密码过期时间。对基于域的用户来说,通过 ADSI 接口的 WINNT:// 协议,可以简单的从 IADsUser::PasswordExpirationDate 获得这一信息;但对于 AD 的 LDAP:// 协议接口,这个字段并不存在,需要我们手工从帐号最后登陆时间 (pwdLastSet) 和用户所在域的帐号过期时间 (maxPwdAge) 自行计算。

    ADSI 接口的 User 对象 schema 中定义了这些常用的属性

    User Object Properties

    微软 MSDN 中也专门有一篇文章详细介绍了如何进行这种计算

    How Long Until My Password Expires?

    其核心算法步骤如下:

    1.帐号是否被禁用
    2.帐号密码是否被设置过
    3.帐号所在域是否有密码期限设置
    4.计算密码期限设置的天数
    5.计算密码过期的时间

    算法流程图如下:

    

    对 VBScript 来说只需要一段简单的代码就可以完成任务

    但因为 .NET v1.x 中活动目录的简陋封装,使得在 .NET 中要实现上述功能相对较为繁琐。

    首先需要通过 AdUser 对象封装的 DirectoryEntry 的属性获得 userAccountControl 字段的值,并判断是否设置了密码永不过期的标志:

    然后需要访问密码最后被重置的时间,判断此帐号是否被使用过。

    这里需要注意的是,密码最后重置时间 (pwdLastSet) 和域密码过期时间 (maxPwdAge) 等字段在 AD 中是 INTEGER8 类型。虽然理论上对应于 C# 中的 long,但通过 System.DirectoryServices 并不能直接访问之。也就是说对于这些 INTEGER8 类型的字段,通过 Convert.ToInt64(Properties["pwdLastSet"][0]) 这样的强制转换调用会直接抛出异常。
    要访问这种字段,必须显式通过 ADSI 规范中的 IADsLargeInteger 接口,手工进行转换。.NET 247 上的一篇文章里面介绍了这个问题的解决方法

    DirectoryEntry __ComObject use.

    而这个例子中的转换代码还可能出现溢出问题,需要小心处理

    Problem with the HighPart and LowPart Property Methods

    完整的转换代码如下:

    只有解决了这诸多问题,才能将上面那一小段 VBScript 代码真正移植到 .NET 下:

    虽然是个小问题,可里面的阻力一点都不小。 希望如 纯朴的狗熊 所说微软会在下个版本里面真正认真对待目录服务这块企业级应用必备的领域。