From: Tomas Weinfurt Date: Mon, 16 Aug 2021 10:16:07 +0000 (-0700) Subject: make use of ports in SPN optional (#57159) X-Git-Tag: accepted/tizen/unified/20220110.054933~370 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=86562e163fc24f776e6df72b19b5f43973feefc7;p=platform%2Fupstream%2Fdotnet%2Fruntime.git make use of ports in SPN optional (#57159) * make port optional in SPN * fix tests * feedback from review * Update src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs Co-authored-by: Stephen Toub * fix build Co-authored-by: Stephen Toub --- diff --git a/src/libraries/Common/tests/System/Net/EnterpriseTests/EnterpriseTestConfiguration.cs b/src/libraries/Common/tests/System/Net/EnterpriseTests/EnterpriseTestConfiguration.cs index e6a9cef..f6ea2e8 100644 --- a/src/libraries/Common/tests/System/Net/EnterpriseTests/EnterpriseTestConfiguration.cs +++ b/src/libraries/Common/tests/System/Net/EnterpriseTests/EnterpriseTestConfiguration.cs @@ -7,6 +7,7 @@ namespace System.Net.Test.Common { public const string Realm = "LINUX.CONTOSO.COM"; public const string NegotiateAuthWebServer = "http://apacheweb.linux.contoso.com/auth/kerberos/"; + public const string NegotiateAuthWebServerNotDefaultPort = "http://apacheweb.linux.contoso.com:8081/auth/kerberos/"; public const string AlternativeService = "http://altweb.linux.contoso.com:8080/auth/kerberos/"; public const string NtlmAuthWebServer = "http://apacheweb.linux.contoso.com:8080/auth/ntlm/"; public const string DigestAuthWebServer = "http://apacheweb.linux.contoso.com/auth/digest/"; diff --git a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/apacheweb/apache2.conf b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/apacheweb/apache2.conf index 87c20f0..a26a52e 100644 --- a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/apacheweb/apache2.conf +++ b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/apacheweb/apache2.conf @@ -54,6 +54,7 @@ Listen 8080 Listen 80 +Listen 8081 # @@ -238,7 +239,7 @@ Group daemon # e-mailed. This address appears on some server-generated pages, such # as error documents. e.g. admin@your-domain.com # -ServerAdmin you@example.com +ServerAdmin webmaster@contoso.com # # ServerName gives the name and port that the server uses to identify itself. @@ -583,11 +584,18 @@ SSLRandomSeed startup builtin SSLRandomSeed connect builtin + - ServerAdmin webmaster@contoso.com DocumentRoot "/setup/altdocs" ServerName altservice.contoso.com:8080 + + + + + DocumentRoot "/setup/htdocs" + + diff --git a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/apacheweb/run.sh b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/apacheweb/run.sh index 6aa9694..0b4a615 100644 --- a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/apacheweb/run.sh +++ b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/apacheweb/run.sh @@ -11,6 +11,7 @@ if [ "$1" == "-debug" ]; then fi if [ "$1" == "-DNTLM" ]; then + # NTLM/Winbind is aggressive and eats Negotiate so it cannot be combined with Kerberos ./setup-pdc.sh /usr/sbin/apache2 -DALTPORT "$@" shift diff --git a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/docker-compose.yml b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/docker-compose.yml index 6aebd7e..c54adfb 100644 --- a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/docker-compose.yml +++ b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/docker-compose.yml @@ -41,7 +41,7 @@ services: hostname: altweb domainname: linux.contoso.com dns_search: linux.contoso.com - command: -DALTPORT + command: "-DALTPORT -DALTSPN" volumes: - shared-volume:/SHARED networks: diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs index 8ee9130..52edbb5 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs @@ -13,6 +13,38 @@ namespace System.Net.Http { internal static partial class AuthenticationHelper { + private const string UsePortInSpnCtxSwitch = "System.Net.Http.UsePortInSpn"; + private const string UsePortInSpnEnvironmentVariable = "DOTNET_SYSTEM_NET_HTTP_USEPORTINSPN"; + + private static volatile int s_usePortInSpn = -1; + + private static bool UsePortInSpn + { + get + { + int usePortInSpn = s_usePortInSpn; + if (usePortInSpn != -1) + { + return usePortInSpn != 0; + } + + // First check for the AppContext switch, giving it priority over the environment variable. + if (AppContext.TryGetSwitch(UsePortInSpnCtxSwitch, out bool value)) + { + s_usePortInSpn = value ? 1 : 0; + } + else + { + // AppContext switch wasn't used. Check the environment variable. + s_usePortInSpn = + Environment.GetEnvironmentVariable(UsePortInSpnEnvironmentVariable) is string envVar && + (envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) ? 1 : 0; + } + + return s_usePortInSpn != 0; + } + } + private static Task InnerSendAsync(HttpRequestMessage request, bool async, bool isProxyAuth, HttpConnectionPool pool, HttpConnection connection, CancellationToken cancellationToken) { return isProxyAuth ? @@ -110,7 +142,7 @@ namespace System.Net.Http hostName = result.HostName; } - if (!isProxyAuth && !authUri.IsDefaultPort) + if (!isProxyAuth && !authUri.IsDefaultPort && UsePortInSpn) { hostName = string.Create(null, stackalloc char[128], $"{hostName}:{authUri.Port}"); } diff --git a/src/libraries/System.Net.Http/tests/EnterpriseTests/HttpClientAuthenticationTest.cs b/src/libraries/System.Net.Http/tests/EnterpriseTests/HttpClientAuthenticationTest.cs index 9b93d53..c2c78d2 100644 --- a/src/libraries/System.Net.Http/tests/EnterpriseTests/HttpClientAuthenticationTest.cs +++ b/src/libraries/System.Net.Http/tests/EnterpriseTests/HttpClientAuthenticationTest.cs @@ -3,7 +3,7 @@ using System.Net.Test.Common; using System.Threading.Tasks; - +using Microsoft.DotNet.RemoteExecutor; using Xunit; namespace System.Net.Http.Enterprise.Tests @@ -11,20 +11,31 @@ namespace System.Net.Http.Enterprise.Tests [ConditionalClass(typeof(EnterpriseTestConfiguration), nameof(EnterpriseTestConfiguration.Enabled))] public class HttpClientAuthenticationTest { + private const string AppContextSettingName = "System.Net.Http.UsePortInSpn"; + [Theory] [InlineData(EnterpriseTestConfiguration.NegotiateAuthWebServer, false)] - [InlineData(EnterpriseTestConfiguration.AlternativeService, false)] + [InlineData(EnterpriseTestConfiguration.NegotiateAuthWebServerNotDefaultPort, false)] + [InlineData(EnterpriseTestConfiguration.AlternativeService, false, true)] [InlineData(EnterpriseTestConfiguration.DigestAuthWebServer, true)] [InlineData(EnterpriseTestConfiguration.DigestAuthWebServer, false)] [InlineData(EnterpriseTestConfiguration.NtlmAuthWebServer, true)] - public async Task HttpClient_ValidAuthentication_Success(string url, bool useDomain) + public void HttpClient_ValidAuthentication_Success(string url, bool useDomain, bool useAltPort = false) { - using var handler = new HttpClientHandler(); - handler.Credentials = useDomain ? EnterpriseTestConfiguration.ValidDomainNetworkCredentials : EnterpriseTestConfiguration.ValidNetworkCredentials; - using var client = new HttpClient(handler); + RemoteExecutor.Invoke((url, useAltPort, useDomain) => + { + // This is safe as we have no parallel tests + if (!string.IsNullOrEmpty(useAltPort)) + { + AppContext.SetSwitch(AppContextSettingName, true); + } + using var handler = new HttpClientHandler(); + handler.Credentials = string.IsNullOrEmpty(useDomain) ? EnterpriseTestConfiguration.ValidNetworkCredentials : EnterpriseTestConfiguration.ValidDomainNetworkCredentials; + using var client = new HttpClient(handler); - using HttpResponseMessage response = await client.GetAsync(url); - Assert.Equal(HttpStatusCode.OK, response.StatusCode); + using HttpResponseMessage response = client.GetAsync(url).GetAwaiter().GetResult(); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + }, url, useAltPort ? "true" : "" , useDomain ? "true" : "").Dispose(); } [ActiveIssue("https://github.com/dotnet/runtime/issues/416")] diff --git a/src/libraries/System.Net.Http/tests/EnterpriseTests/System.Net.Http.Enterprise.Tests.csproj b/src/libraries/System.Net.Http/tests/EnterpriseTests/System.Net.Http.Enterprise.Tests.csproj index 5d1c6c0..4af21d6 100644 --- a/src/libraries/System.Net.Http/tests/EnterpriseTests/System.Net.Http.Enterprise.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/EnterpriseTests/System.Net.Http.Enterprise.Tests.csproj @@ -1,6 +1,7 @@ $(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser + true @@ -8,4 +9,4 @@ - \ No newline at end of file +