96 lines
4.4 KiB
C#
96 lines
4.4 KiB
C#
using System.Security.Claims;
|
|
using System.Text.Encodings.Web;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
using ZB.MOM.WW.Auth.AspNetCore;
|
|
using ZB.MOM.WW.MxGateway.Server.Configuration;
|
|
|
|
namespace ZB.MOM.WW.MxGateway.Server.Dashboard;
|
|
|
|
/// <summary>
|
|
/// Authentication handler used ONLY when <c>MxGateway:Dashboard:DisableLogin</c> is true.
|
|
/// Registered under the dashboard cookie scheme name
|
|
/// (<see cref="DashboardAuthenticationDefaults.AuthenticationScheme"/>), it authenticates
|
|
/// EVERY request as the configured dev user with both dashboard roles — no credential check,
|
|
/// no cookie, no LDAP bind. The minted principal mirrors the shape the real login
|
|
/// (<see cref="DashboardAuthenticator"/>) produces, so policies and the UI cannot tell it
|
|
/// apart. DEV/TEST ONLY; never enable in production.
|
|
/// </summary>
|
|
public sealed class DashboardAutoLoginAuthenticationHandler
|
|
: AuthenticationHandler<AuthenticationSchemeOptions>, IAuthenticationSignInHandler
|
|
{
|
|
/// <summary>Username used when <c>AutoLoginUser</c> is null or blank.</summary>
|
|
public const string DefaultUser = "multi-role";
|
|
|
|
private readonly string _user;
|
|
|
|
/// <summary>Initializes the handler with scheme plumbing and the dashboard options.</summary>
|
|
/// <param name="options">The per-scheme authentication options monitor.</param>
|
|
/// <param name="logger">The logger factory the base handler uses.</param>
|
|
/// <param name="encoder">The URL encoder the base handler uses.</param>
|
|
/// <param name="gatewayOptions">Gateway options carrying the dashboard auto-login user.</param>
|
|
public DashboardAutoLoginAuthenticationHandler(
|
|
IOptionsMonitor<AuthenticationSchemeOptions> options,
|
|
ILoggerFactory logger,
|
|
UrlEncoder encoder,
|
|
IOptions<GatewayOptions> gatewayOptions)
|
|
: base(options, logger, encoder)
|
|
{
|
|
string? configured = gatewayOptions.Value.Dashboard.AutoLoginUser;
|
|
_user = string.IsNullOrWhiteSpace(configured) ? DefaultUser : configured.Trim();
|
|
}
|
|
|
|
/// <summary>No-op: auto-login writes no cookie, so a sign-in has nothing to persist.</summary>
|
|
/// <param name="user">Ignored.</param>
|
|
/// <param name="properties">Ignored.</param>
|
|
/// <returns>A completed task.</returns>
|
|
public Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties? properties) => Task.CompletedTask;
|
|
|
|
/// <summary>No-op: there is no auth cookie to clear; the next request re-authenticates.</summary>
|
|
/// <param name="properties">Ignored.</param>
|
|
/// <returns>A completed task.</returns>
|
|
public Task SignOutAsync(AuthenticationProperties? properties) => Task.CompletedTask;
|
|
|
|
/// <inheritdoc />
|
|
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
|
{
|
|
ClaimsPrincipal principal = CreatePrincipal(_user);
|
|
AuthenticationTicket ticket = new(principal, Scheme.Name);
|
|
|
|
return Task.FromResult(AuthenticateResult.Success(ticket));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the multi-role dev principal. Null/blank <paramref name="user"/> falls back to
|
|
/// <see cref="DefaultUser"/>. The authorization-relevant claim shape mirrors
|
|
/// <see cref="DashboardAuthenticator"/>; LDAP group claims (<c>LdapGroupClaimType</c>) are
|
|
/// intentionally omitted because auto-login has no real LDAP context.
|
|
/// </summary>
|
|
/// <param name="user">The configured auto-login username (may be null/blank).</param>
|
|
/// <returns>An authenticated principal holding both dashboard roles.</returns>
|
|
internal static ClaimsPrincipal CreatePrincipal(string? user)
|
|
{
|
|
string name = string.IsNullOrWhiteSpace(user) ? DefaultUser : user.Trim();
|
|
|
|
// LdapGroupClaimType claims are omitted — no LDAP groups exist in the auto-login context.
|
|
Claim[] claims =
|
|
[
|
|
new Claim(ClaimTypes.NameIdentifier, name),
|
|
new Claim(ZbClaimTypes.Username, name),
|
|
new Claim(ZbClaimTypes.Name, name),
|
|
new Claim(ZbClaimTypes.DisplayName, name),
|
|
new Claim(ZbClaimTypes.Role, DashboardRoles.Admin),
|
|
new Claim(ZbClaimTypes.Role, DashboardRoles.Viewer),
|
|
];
|
|
|
|
ClaimsIdentity identity = new(
|
|
claims,
|
|
DashboardAuthenticationDefaults.AuthenticationScheme,
|
|
ZbClaimTypes.Name,
|
|
ZbClaimTypes.Role);
|
|
|
|
return new ClaimsPrincipal(identity);
|
|
}
|
|
}
|