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()