@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; } } }