透过 ASP.NET Core 写一个简易的 AD 帐号密码验证 Web API

  最近试着透过 ASP.NET Core 写一个 AD 帐密修改的程式,架构上大致是先有个 AD 验证及些密码修改的 Web API,最后再写一个桌面应用程式,让使用者自行修改。这次完成的是帐密验证的 Web API,程式如下:

《专案范本》

  • ASP .NET Core Web API

《NuGet 安裝套件》

  • 系统.目录服务.协议 (AD 套件)
  • 虚张声势.AspNetCore (API 测试套件,或是在新增专案时,勾选 OpenAPI 亦可)

服务/UserPasswordService.cs

using System.DirectoryServices.Protocols;
using System.Net;

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

        public bool Validate(string username, string password)
        {
            try
            {
                var credentials = username;
                using var connection = new LdapConnection(new LdapDirectoryIdentifier(_ldapServer));
                connection.Credential = new NetworkCredential(username, password, _domain);
                connection.AuthType = AuthType.Negotiate; // 使用 Negotiate 會先嘗試 Kerberos,失敗再改試 NTLM。
                connection.Bind(); // 嘗試綁定,成功表示驗證通過
                return true;
            }
            catch (LdapException)
            {
                return false; // 驗證失敗
            }
        }
    }
}

控制器/PasswordValidationController.cs

using AD.Services;
using AD.Models;
using Microsoft.AspNetCore.Mvc;

namespace AD.Controllers
{
    [Route("Password-Validate")]
    [ApiController]

    public class PasswordValidationController(UserPasswordService userPassword) : ControllerBase
    {
        [HttpPost("validate")]
        public IActionResult Validate([FromBody] LoginRequest request)
        {
            if (string.IsNullOrWhiteSpace(request.Username) || string.IsNullOrWhiteSpace(request.Password))
            {
                return BadRequest("使用者帳號或密碼不可為空白。");
            }

            var isValid = userPassword.ValidatePassword(request.Username, request.Password);
            return isValid ? Ok("驗證成功。") : Unauthorized("驗證失敗。");
        }
    }
}

模型/LoginRequestDTO.cs

namespace AD.Models
{
    public class LoginRequestDTO
    {
        public string Username { get; set; } // DTO (Data Transfer Object) 類型的屬性不需要初始化,因為它們的值由外部輸入資料 (例如 HTTP 請求) 決定。
        public string Password { get; set; }
    }
}

模型/LdapSettings.cs

namespace AD.Models
{
    public class LdapSettings
    {
        public string Server { get; set; } = string.Empty;
        public string Domain { get; set; } = string.Empty;
    }
}

应用程序设置.json

{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft.AspNetCore": "Warning"
        }
    },

    "AllowedHosts": "*",

    "LdapSettings": {
        "Server": "dc.abc.com.tw", // 如果是用 Kerberos 驗證,AD 的伺服器不可以使用 IP。
        "Domain": "abc"
    }
}

程序.cs

using AD.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
builder.Services.Configure<LdapSettings>(builder.Configuration.GetSection("LdapSettings")); // 讀取 appsettings.json 的 LdapSettings 資料。
builder.Services.AddScoped<UserPasswordService>();

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.

// 讓 Swagger 只在開發環境時使用。
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

要测试时,透过 Swagger,输入帐号密码测试即可。

4 回应

  1. 老森常谭 IT Help » 以 .NET MAUI Blazor 撰写 AD 密码修改的桌面应用程式 (搭配Web API) 说: |

    […]   完成了《AD 密碼驗證》與《AD 密碼修改》兩個 API 後,接下来用 .NET MAUI Blazor 来写桌面端的程式。稍微了解了 Blazor 后,觉得好神奇,感觉就是把网页塞进应用程式里面,运行时还可以在「工作管理员」看到背后有 Edge 的相关元件在运行,然后按 F12 还会有开发者工具视窗!不过这也让我衍生了一点安全性的疑虑。但整体感觉还是挺特别的,刚好我对网页语法比较熟,搭配 Razor 来设计 UI 画面,感觉亲切不少。 […]

  2. 老森常谭 IT Help » 透过 ASP.NET Core 写一个让使用者可以修改自己 AD 密码的 Web API 说: |

    […] 验证 AD 密码的 API […]

  3. 肖恩 说: |

    兄弟,软体功力越来越强啰!

    因为最近认识了一个很给力的兄弟叫 AI 😀

    陈方安生 回复 |

发表评论

请注意:: 评论审核已启用,可能会耽误您的评论. 有没有必要重新提交您的评论.