fix(auth): MxGateway 1.2 review fixes — group-claim doc, dedup LdapOptions, 0.1.1 pin
This commit is contained in:
@@ -81,9 +81,10 @@ public sealed class DashboardAuthenticatorTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On success the principal carries the resolved roles, the raw LDAP-group claims,
|
||||
/// the display name (ClaimTypes.Name), and the username (ClaimTypes.NameIdentifier),
|
||||
/// under the dashboard authentication scheme — the exact shape produced before the cutover.
|
||||
/// On success the principal carries the resolved roles, the LDAP-group claims
|
||||
/// (short RDN names as returned by <see cref="ILdapAuthService"/>), the display
|
||||
/// name (ClaimTypes.Name), and the username (ClaimTypes.NameIdentifier), under the
|
||||
/// dashboard authentication scheme.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task AuthenticateAsync_Success_BuildsPrincipalWithExpectedClaims()
|
||||
@@ -115,7 +116,8 @@ public sealed class DashboardAuthenticatorTests
|
||||
Assert.True(principal.IsInRole(DashboardRoles.Admin));
|
||||
Assert.True(principal.IsInRole(DashboardRoles.Viewer));
|
||||
|
||||
// Raw LDAP groups are surfaced under the dedicated group claim type.
|
||||
// LDAP groups (already short RDN names from the service) are surfaced under
|
||||
// the dedicated group claim type.
|
||||
IReadOnlyList<string> groupClaims = principal.FindAll(
|
||||
DashboardAuthenticationDefaults.LdapGroupClaimType)
|
||||
.Select(claim => claim.Value)
|
||||
@@ -146,11 +148,22 @@ public sealed class DashboardAuthenticatorTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A group supplied as a full distinguished name still resolves to its role via the
|
||||
/// mapper's leading-RDN fallback, and the original DN is preserved on the group claim.
|
||||
/// Direct-injection path only (review C1): when an <see cref="ILdapAuthService"/>
|
||||
/// implementation hands the authenticator a full distinguished name as a group, the
|
||||
/// mapper's leading-RDN fallback still resolves the role, and whatever string the
|
||||
/// service supplied is surfaced verbatim on the group claim.
|
||||
/// <para>
|
||||
/// This is NOT the real production flow. The shared <c>ZB.MOM.WW.Auth.Ldap</c>
|
||||
/// provider strips each group DN to its short RDN name before returning it, so the
|
||||
/// authenticator never receives a full DN from the real library and the group claim
|
||||
/// in production carries the short name (e.g. <c>GwAdmin</c>), not the DN. This test
|
||||
/// uses a fake service to exercise only the authenticator's own pass-through of group
|
||||
/// values; see <see cref="AuthenticateAsync_Success_BuildsPrincipalWithExpectedClaims"/>
|
||||
/// for the realistic (already-short) group shape.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task AuthenticateAsync_GroupAsDistinguishedName_ResolvesRoleAndPreservesGroupClaim()
|
||||
public async Task AuthenticateAsync_GroupAsDistinguishedNameFromService_ResolvesRoleAndSurfacesServiceValue()
|
||||
{
|
||||
const string groupDn = "ou=GwAdmin,ou=groups,dc=lmxopcua,dc=local";
|
||||
FakeLdapAuthService ldap = new(LdapAuthResult.Success(
|
||||
@@ -166,7 +179,10 @@ public sealed class DashboardAuthenticatorTests
|
||||
|
||||
Assert.True(result.Succeeded);
|
||||
ClaimsPrincipal principal = Assert.IsType<ClaimsPrincipal>(result.Principal);
|
||||
// Role resolves via the leading-RDN fallback in DashboardGroupRoleMapping.
|
||||
Assert.True(principal.IsInRole(DashboardRoles.Admin));
|
||||
// The authenticator surfaces the value the (fake) service returned, verbatim.
|
||||
// With the real library this value would already be the short RDN ("GwAdmin").
|
||||
Assert.Contains(
|
||||
principal.FindAll(DashboardAuthenticationDefaults.LdapGroupClaimType),
|
||||
claim => claim.Value == groupDn);
|
||||
|
||||
Reference in New Issue
Block a user