【问题标题】:How to learn whether a user password is expired or not in Active Directory?如何在 Active Directory 中了解用户密码是否过期?
【发布时间】:2015-04-10 08:03:36
【问题描述】:

在我的 ASP.NET MVC (C#) 项目中,我必须了解用户密码是否过期?我在互联网上找到了一些关于此的答案,但它们对我没有用。

第一种方法是使用maxpwdage+pwdlastset=password expired date,第二种方法是使用useraccountcontrol属性来了解是否过期。如果该属性的值为8389120,则用户密码已过期。

虽然用户密码在 AD 中已过期,useraccountcontrolvalue 仍然是 512。我尝试使用 maxpwdage+pwdlastset 但我看不到像 maxpwdage 这样的属性(我让用户成为管理员)

Active Directory user password expiration date .NET/OU Group Policy (第一种方式) https://support.microsoft.com/en-us/kb/305144(第二种方式)

由于我上面提到的原因,它们都无法正常工作。

还有其他方法可以做到这一点,或者我如何查看maxpwdage 属性的值?

编辑:我从这里得到我想要的用户

            DirectoryEntry dEntry = new DirectoryEntry
                        ( "LDAP://a.b.c:123/OU=d, DC=e, DC=f", this.GetAdUserName(),
                        this.GetAdUserPassword() );
            DirectorySearcher directorySearcher = new DirectorySearcher( dEntry );
            directorySearcher.Asynchronous = true;
            directorySearcher.CacheResults = true;
            directorySearcher.Filter = "(&(sAMaccountName=" + identificationNumber + "))";
            SearchResult user = directorySearcher.FindOne();
            return user;

我正在检查用户的属性,但找不到maxpwdage 属性。

【问题讨论】:

  • 您可能必须加载 maxPwdAge 属性。 userEntry.RefreshCache(new string[] { "maxPwdAge" });
  • 您使用什么异常来捕获例如密码错误时发生的异常?
  • @manuchao 我试过 userEntry.RefreshCache(new string[] { "maxPwdAge" });但我仍然看不到 maxpwdage 属性。

标签: c# asp.net-mvc active-directory


【解决方案1】:

您可以使用代表时间间隔的TimeSpan。然后您只需要检查今天的日期和过期日期。

DateTime expireDate = passwordLastChanged.AddDays(iMaxPwdAge);
TimeSpan ts = expireDate - DateTime.Now;
int iDaysTilExpired = ts.Days;
WriteLogMessage("Days til password expires:" + iDaysTilExpired);

还有一个很好的example,我为我的项目更改了一些部分,它对我有用。

编辑:

您可以使用属性msDS-UserPasswordExpiryTimeComputed 获取用户密码到期日期。

还有

“maxPwdAge”属性保留在 domainDNS 类(目录的根)上,因为它是策略的一部分。它不保存在用户对象上。如果您使用的是 .NET 2.0,则可以轻松获得:

using (DirectoryEntry domain = Domain.GetCurrentDomain())
{
    DirectorySearcher ds = new DirectorySearcher(
        domain,
        "(objectClass=*)",
        null,
        SearchScope.Base
        );

        SearchResult sr = ds.FindOne();

        TimeSpan maxPwdAge = TimeSpan.MinValue;

        if (sr.Properties.Contains("maxPwdAge"))
            maxPwdAge = TimeSpan.FromTicks((long)sr.Properties["maxPwdAge"][0]);
}

编辑 2:

这是您可以使用的完整示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;

namespace LDAP
{
    class Program
    {
        static void Main(string[] args)
        {
            string domainAndUsername = string.Empty;
            string domain = string.Empty;
            string userName = string.Empty;
            string passWord = string.Empty;
            AuthenticationTypes at = AuthenticationTypes.Anonymous;
            StringBuilder sb = new StringBuilder();

            domain = @"LDAP://w.x.y.z";
            domainAndUsername = @"LDAP://w.x.y.z/cn=Lawrence E."+
                        " Smithmier\, Jr.,cn=Users,dc=corp,"+
                        "dc=productiveedge,dc=com";
            userName = "Administrator";
            passWord = "xxxpasswordxxx";
            at = AuthenticationTypes.Secure;

            DirectoryEntry entry = new DirectoryEntry(
                        domain, userName, passWord, at);

            DirectorySearcher mySearcher = new DirectorySearcher(entry);

            SearchResultCollection results;
            string filter = "maxPwdAge=*";
            mySearcher.Filter = filter;

            results = mySearcher.FindAll();
            long maxDays = 0;
            if(results.Count>=1)
            {
                Int64 maxPwdAge=(Int64)results[0].Properties["maxPwdAge"][0];
                maxDays = maxPwdAge/-864000000000;
            }

            DirectoryEntry entryUser = new DirectoryEntry(
                        domainAndUsername, userName, passWord, at);
            mySearcher = new DirectorySearcher(entryUser);

            results = mySearcher.FindAll();
            long daysLeft=0;
            if (results.Count >= 1)
            {
                var lastChanged = results[0].Properties["pwdLastSet"][0];
                daysLeft = maxDays - DateTime.Today.Subtract(
                        DateTime.FromFileTime((long)lastChanged)).Days;
            }
            Console.WriteLine(
                        String.Format("You must change your password within"+
                                      " {0} days"
                                     , daysLeft));
            Console.ReadLine();
        }
    }
}

【讨论】:

  • 我不知道过期日期。问题是
  • 感谢您的帮助,我完全按照您说的做了,但我仍然无法在 14 个属性中看到 maxPwdAge。
  • @UygarKahraman 请提供更多信息,是否有任何错误?,您在哪一步失败,为什么看不到?你在使用管理员权限吗?
  • 我没有收到任何错误或异常。我必须确定过期日期并将密码过期的用户重定向到“更改密码页面”。为此,我必须了解他/她的密码是否过期,为此我必须使用 maxpwdage 属性。我有管理员权限,我得到了我想要的用户,我正在查看这个用户的属性。 MaxPwdAge 不在这些属性中。这就是问题
  • 那你为什么不用 "maxPwdAge=*" 过滤用户呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
  • 1970-01-01
  • 2013-04-24
  • 2016-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多