@page "/login"
@using System.Security.Claims
@using Microsoft.AspNetCore.Authentication
@using Microsoft.AspNetCore.Authentication.Cookies
@using ZB.MOM.WW.OtOpcUa.Admin.Security
@inject IHttpContextAccessor Http
@inject ILdapAuthService LdapAuth
@inject NavigationManager Nav
OtOpcUa Admin — sign in
@if (_error is not null) { @_error
}
LDAP bind against the configured directory. Dev defaults to GLAuth on
localhost:3893.
@code {
private sealed class Input
{
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
private Input _input = new();
private string? _error;
private bool _busy;
private async Task SignInAsync()
{
_error = null;
_busy = true;
try
{
if (string.IsNullOrWhiteSpace(_input.Username) || string.IsNullOrWhiteSpace(_input.Password))
{
_error = "Username and password are required";
return;
}
var result = await LdapAuth.AuthenticateAsync(_input.Username, _input.Password, CancellationToken.None);
if (!result.Success)
{
_error = result.Error ?? "Sign-in failed";
return;
}
if (result.Roles.Count == 0)
{
_error = "Sign-in succeeded but no Admin roles mapped for your LDAP groups. Contact your administrator.";
return;
}
var ctx = Http.HttpContext
?? throw new InvalidOperationException("HttpContext unavailable at sign-in");
var claims = new List
{
new(ClaimTypes.Name, result.DisplayName ?? result.Username ?? _input.Username),
new(ClaimTypes.NameIdentifier, _input.Username),
};
foreach (var role in result.Roles)
claims.Add(new Claim(ClaimTypes.Role, role));
foreach (var group in result.Groups)
claims.Add(new Claim("ldap_group", group));
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await ctx.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(identity));
ctx.Response.Redirect("/");
}
finally { _busy = false; }
}
}