diff --git a/Controllers/AuthController.cs b/Controllers/AuthController.cs
index a2fc353..1727589 100644
--- a/Controllers/AuthController.cs
+++ b/Controllers/AuthController.cs
@@ -1,5 +1,8 @@
-using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
+using System.Security.Principal;
+using FakeNTLMServer.Model;
+using FakeNTLMServer.Common;
namespace FakeNTLMServer.Controllers;
@@ -23,7 +26,7 @@ public class AuthController : ControllerBase
///
/// NTLM/Negotiate login endpoint.
- /// Triggers the NTLM handshake (401 → challenge → response) and returns authenticated user info.
+ /// Triggers the NTLM handshake and returns authenticated user info.
///
[Authorize]
[HttpGet("login")]
@@ -44,6 +47,51 @@ public class AuthController : ControllerBase
});
}
+ ///
+ /// Validates Windows credentials (username/password) using the Win32 LogonUser API.
+ /// Works on local Kestrel without IIS or Negotiate middleware.
+ ///
+ [AllowAnonymous]
+ [HttpPost("login")]
+ public IActionResult LoginWithCredentials([FromBody] Login request)
+ {
+ var username = request.Username;
+ var domain = request.Domain ?? ".";
+
+ if (username.Contains('\\'))
+ {
+ var parts = username.Split('\\', 2);
+ domain = parts[0];
+ username = parts[1];
+ }
+ else if (username.Contains('@'))
+ {
+ var parts = username.Split('@', 2);
+ username = parts[0];
+ domain = parts[1];
+ }
+
+ if (!NtlmHelper.ValidateCredentials(username, domain, request.Password, out var token))
+ {
+ return Unauthorized(new { Message = "Invalid username or password." });
+ }
+
+ using (token)
+ {
+ var windowsIdentity = new WindowsIdentity(token.DangerousGetHandle());
+ var claims = windowsIdentity.Claims.Select(c => new { c.Type, c.Value }).ToList();
+
+ return Ok(new
+ {
+ Message = "Authentication successful.",
+ Name = windowsIdentity.Name,
+ AuthenticationType = windowsIdentity.AuthenticationType,
+ IsAuthenticated = windowsIdentity.IsAuthenticated,
+ Claims = claims
+ });
+ }
+ }
+
[Authorize]
[HttpGet("status")]
public IActionResult Status()