From 5dc1adbc87fc8950a3381757f7d51815878eca72 Mon Sep 17 00:00:00 2001 From: Carol Wang Date: Sat, 12 Oct 2024 16:04:01 +0800 Subject: [PATCH 1/2] Stop splitting the UPN credential into username and domain parts unless specified. --- .../src/System/ServiceModel/Security/SecurityUtils.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/System.ServiceModel.Primitives/src/System/ServiceModel/Security/SecurityUtils.cs b/src/System.ServiceModel.Primitives/src/System/ServiceModel/Security/SecurityUtils.cs index 941f9c54640..41fc68f66fc 100644 --- a/src/System.ServiceModel.Primitives/src/System/ServiceModel/Security/SecurityUtils.cs +++ b/src/System.ServiceModel.Primitives/src/System/ServiceModel/Security/SecurityUtils.cs @@ -201,6 +201,8 @@ internal static partial class SecurityUtils public const string Principal = "Principal"; private static IIdentity s_anonymousIdentity; private static X509SecurityTokenAuthenticator s_nonValidatingX509Authenticator; + internal const string EnableLegacyUpnUsernameFixString = "Switch.System.ServiceModel.EnableLegacyUpnUsernameFix"; + internal static bool s_enableLegacyUpnUsernameFix = AppContext.TryGetSwitch(EnableLegacyUpnUsernameFixString, out bool enabled) && enabled; internal static string GetSpnFromIdentity(EndpointIdentity identity, EndpointAddress target) { @@ -932,6 +934,11 @@ public static SecurityBindingElement GetIssuerSecurityBindingElement(ServiceMode } internal static void FixNetworkCredential(ref NetworkCredential credential) + { + FixNetworkCredential(ref credential, s_enableLegacyUpnUsernameFix); + } + + internal static void FixNetworkCredential(ref NetworkCredential credential, bool enableLegacyUpnUsernameFix) { if (credential == null) { @@ -952,7 +959,7 @@ internal static void FixNetworkCredential(ref NetworkCredential credential) credential = new NetworkCredential(partsWithSlashDelimiter[1], credential.Password, partsWithSlashDelimiter[0]); } } - else if (partsWithSlashDelimiter.Length == 1 && partsWithAtDelimiter.Length == 2) + else if (enableLegacyUpnUsernameFix && partsWithSlashDelimiter.Length == 1 && partsWithAtDelimiter.Length == 2) { if (!string.IsNullOrEmpty(partsWithAtDelimiter[0]) && !string.IsNullOrEmpty(partsWithAtDelimiter[1])) { From 1912b595df6faed249e6edb7d8f47a78511245e4 Mon Sep 17 00:00:00 2001 From: Carol Wang Date: Thu, 17 Oct 2024 17:11:50 +0800 Subject: [PATCH 2/2] Add unit test. --- .../tests/Security/SecurityUtilsTest.cs | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/System.ServiceModel.Primitives/tests/Security/SecurityUtilsTest.cs diff --git a/src/System.ServiceModel.Primitives/tests/Security/SecurityUtilsTest.cs b/src/System.ServiceModel.Primitives/tests/Security/SecurityUtilsTest.cs new file mode 100644 index 00000000000..4344acda2e3 --- /dev/null +++ b/src/System.ServiceModel.Primitives/tests/Security/SecurityUtilsTest.cs @@ -0,0 +1,48 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Net; +using System.Reflection; +using System.ServiceModel.Security; +using Infrastructure.Common; +using Xunit; + +public static class SecurityUtilsTest +{ + [WcfFact] + public static void FixNetworkCredential_AppContext_EnableLegacyUpnUsernameFix() + { + Type t = Assembly.GetAssembly(typeof(WindowsClientCredential)) + .GetType(typeof(WindowsClientCredential).Namespace + ".SecurityUtils"); + + MethodInfo method = t.GetMethod("FixNetworkCredential", BindingFlags.NonPublic | BindingFlags.Static, + null, new[] { typeof(NetworkCredential).MakeByRefType() }, null); + + //switch on + var credential = new NetworkCredential("user@domain.com", "password"); + var parameters = new object[] { credential }; + AppContext.SetSwitch("Switch.System.ServiceModel.EnableLegacyUpnUsernameFix", true); + method.Invoke(null, parameters); + + credential = (NetworkCredential)parameters[0]; + Assert.NotNull(credential); + Assert.Equal("user", credential.UserName); + Assert.Equal("password", credential.Password); + Assert.Equal("domain.com", credential.Domain); + + //switch off + FieldInfo f = t.GetField("s_enableLegacyUpnUsernameFix", BindingFlags.Static | BindingFlags.NonPublic); + f.SetValue(t, false); + credential = new NetworkCredential("user@domain.com", "password"); + parameters = new object[] { credential }; + method.Invoke(null, parameters); + + credential = (NetworkCredential)parameters[0]; + Assert.NotNull(credential); + Assert.Equal("user@domain.com", credential.UserName); + Assert.Equal("password", credential.Password); + Assert.Equal(string.Empty, credential.Domain); + } +}