ASP.NET कोर - एक वेब एपीआई जो एडी उपयोगकर्ता पासवर्ड के लिए क्वेरी करता है जो समाप्त होने वाले हैं

पिछले दो AD पासवर्ड-संबंधित API का जारी रहना,इसके बाद, एक एपीआई लिखा गया था जो एडी उपयोगकर्ता पासवर्ड की समाप्ति को क्वेरी कर सकता था,यह पर्यावरण के बारे में विस्तार से नहीं जाएगा,मॉडल शामिल हैं、ऐप्ससेटिंग्स.जेसन、Program.cs आदि,क्योंकि यह पिछली परियोजना की निरंतरता है,यदि आवश्यक हो, तो आप पिछले लेख का उल्लेख कर सकते हैं。


सेवाएँ/पासवर्ड प्रबंधनService.cs

using AD.Models;
using Microsoft.Extensions.Options;
using System.DirectoryServices;
using System.DirectoryServices.Protocols;
using System.Net;
using System.Text;
using System.DirectoryServices.AccountManagement;
using System.Runtime.Versioning;


namespace AD.Services
{
    public class PasswordManagementService(IOptions<LdapSettings> ldapSettings)
    {
        private readonly string _ldapServer = ldapSettings.Value.Server;
        private readonly string _domain = ldapSettings.Value.Domain;
        private readonly string _baseDn = ldapSettings.Value.BaseDn;

        // 查詢網域密碼政策
        [SupportedOSPlatform("windows")] // 宣告以下方法僅適用於 Windows,避免 DirectorySearcher 等 class 被提示要留意跨平臺問題。
        public TimeSpan GetMaxPasswordAge()
        {
            try
            {
                // 使用 DirectorySearcher 查詢網域《群組原則》的「密碼最長使用期限」。
                using DirectorySearcher searcher = new(new DirectoryEntry($"LDAP://{_baseDn}"))
                {
                    Filter = "(objectClass=domain)"
                };
                searcher.PropertiesToLoad.Add("maxPwdAge"); // 密碼最長使用期限

                SearchResult? result = searcher.FindOne();

                if (result != null && result.Properties.Contains("maxPwdAge"))
                {
                    long maxPwdAgeTicks = (long)result.Properties["maxPwdAge"][0]; // 「密碼最長使用期限」原始數值,
                    return TimeSpan.FromTicks(maxPwdAgeTicks); // 轉成 TimeSpan 物件。(TimeSpan 物件在時間處理較為方便)
                }

                return TimeSpan.Zero; // 找不到資料時,回傳 0
            }
            catch (Exception ex)
            {
                Console.WriteLine($"查詢網域密碼政策時,發生錯誤: {ex.Message}");
                return TimeSpan.Zero;
            }
        }

        // 查詢密碼即將到期的使用者
        [SupportedOSPlatform("windows")] // 宣告以下方法僅適用於 Windows,避免 GetMaxPasswordAge() 等方法被提示要留意跨平臺問題。
        public List<String> GetUsersWithExpiringPasswords(int daysUntilExpiry)
        {
            List<String> expiringUsers = []; // 「密碼即將到期的使用者」清單。

            try
            {
                TimeSpan MaxPasswordAge = GetMaxPasswordAge(); // 取得「密碼最長使用期限」。

                if (MaxPasswordAge == TimeSpan.Zero) // 未設定「密碼最長使用期限」。
                    return expiringUsers;

                DateTime today = DateTime.Now;
                DateTime thresholdDate = today.AddDays(daysUntilExpiry); // XX 天 (daysUntilExpiry) 後的「到期日期」。

                // 使用 DirectorySearcher 查詢網域《群組原則》的「密碼最長使用期限」。
                using DirectorySearcher searcher = new(new DirectoryEntry($"LDAP://{_baseDn}"))
                {
                    Filter = "(&(objectCategory=person)(objectClass=user)(pwdLastSet=*)(mail=*))" // 篩選有「上次密碼設定時間」、「Mail」的「使用者」。
                };
                searcher.PropertiesToLoad.Add("sAMAccountName"); // AD 帳號
                searcher.PropertiesToLoad.Add("pwdLastSet");     // 上次密碼設定時間
                searcher.PropertiesToLoad.Add("displayName");    // 顯示名稱
                searcher.PropertiesToLoad.Add("mail");           // 電子郵件

                foreach (SearchResult result in searcher.FindAll())
                {
                    long pwdLastSetTicks = (long)result.Properties["pwdLastSet"][0]; // 使用者帳戶的「上次密碼設定時間」。
                    DateTime pwdLastSet = DateTime.FromFileTime(pwdLastSetTicks);    // 轉成 DateTime 格式。(具體的日期)
                    DateTime passwordExpiryDate = pwdLastSet + MaxPasswordAge;       // 使用者帳戶的「密碼到期日」。

                    if (passwordExpiryDate <= thresholdDate) // 已經到期或未來 XX 天內會到期的帳戶
                    {
                        string userSAMAccountName = result.Properties["sAMAccountName"][0].ToString() ?? string.Empty; // AD 帳號
                        string userPasswordExpiryDate = passwordExpiryDate.ToString("yyyy/MM/dd") ?? string.Empty;     // 上次密碼設定時間
                        string userDisplayName = result.Properties["displayName"][0].ToString() ?? string.Empty;       // 顯示名稱
                        string userMail = result.Properties["mail"][0].ToString() ?? string.Empty;                     // 電子郵件

                        string expiringUsersInfo = $"{userSAMAccountName};{userPasswordExpiryDate};{userDisplayName};{userMail}";
                        expiringUsers.Add(expiringUsersInfo);
                    }
                }

                return expiringUsers; // 若沒結果,回傳空的清單。
            }
            catch (Exception ex)
            {
                Console.WriteLine($"查詢密碼即將到期的使用者時,發生錯誤: {ex.Message}");
                return expiringUsers;
            }
        }
    }
}

 

नियंत्रक/पासवर्ड प्रबंधन नियंत्रक.सीएस

using AD.Models;
using AD.Services;
using Microsoft.AspNetCore.Mvc;
using System.Runtime.Versioning;

namespace AD.Controllers
{
    [Route("password")]
    [ApiController]

    public class PasswordManagementController(PasswordManagementService passwordManagement) : ControllerBase
    {

        // 取得密碼即將到期的使用者
        [HttpGet("get-expiry-users/{days}")]
        [SupportedOSPlatform("windows")] // 宣告以下用到的方法僅適用於 Windows,避免 GetUsersWithExpiringPasswords 方法被提示要留意跨平臺問題。

        public IActionResult GetExpiringUsers(int days)
        {
            try
            {
                var users = passwordManagement.GetUsersWithExpiringPasswords(days);
                return Ok(new { expiringUsers = users }); // 回傳一個包含 ExpiringUsers 屬性,其值為 users 的 JSON 格式。
            }
            catch (Exception ex) {
                return StatusCode(500, new { Message = "發生錯誤", Error = ex.Message });
            }
        }
    }
}

 

स्वैगर टेस्ट के नतीजे

 

"संबंधित लिंक"

एक टिप्पणी छोड़ दो

कृपया ध्यान दें: टिप्पणी मॉडरेशन सक्षम है और अपनी टिप्पणी में देरी हो सकती है. कोई जरूरत नहीं अपनी टिप्पणी को पुनः सबमिट करने की आवश्यकता है.