| File: System\ServiceModel\Channels\TransportSecurityHelpers.cs | Web Access |
| Project: src\src\System.ServiceModel.NetFramingBase\src\System.ServiceModel.NetFramingBase.csproj (System.ServiceModel.NetFramingBase) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.IdentityModel.Selectors; using System.IdentityModel.Tokens; using System.Net; using System.Security.Principal; using System.ServiceModel.Security; using System.ServiceModel.Security.Tokens; using System.Threading.Tasks; namespace System.ServiceModel.Channels { internal static class WindowsStreamTransportSecurityHelpers { //// used for HTTP (from HttpChannelUtilities.GetCredential) //public static async ValueTask<(NetworkCredential credential, TokenImpersonationLevel impersonationLevel, AuthenticationLevel authenticationLevel)> GetSspiCredentialAsync( // SecurityTokenProviderContainer tokenProvider, TimeSpan timeout) //{ // var result = await GetSspiCredentialCoreAsync(tokenProvider.TokenProvider as SspiSecurityTokenProvider, timeout); // AuthenticationLevel authenticationLevel = result.allowNtlm ? AuthenticationLevel.MutualAuthRequested : AuthenticationLevel.MutualAuthRequired; // return (result.credential, result.impersonationLevel, authenticationLevel); //} // used by client WindowsStream security (from InitiateUpgrade) public static async ValueTask<(NetworkCredential credential, TokenImpersonationLevel impersonationLevel, bool allowNtlm)> GetSspiCredentialAsync(SecurityTokenProvider tokenProvider, TimeSpan timeout) { var result = await GetSspiCredentialCoreAsync(tokenProvider, timeout); return (result.credential, result.impersonationLevel, result.allowNtlm); } // core Cred lookup code public static async ValueTask<(NetworkCredential credential, bool extractGroupsForWindowsAccounts, TokenImpersonationLevel impersonationLevel, bool allowNtlm)> GetSspiCredentialCoreAsync( SecurityTokenProvider tokenProvider, TimeSpan timeout) { (NetworkCredential credential, bool extractGroupsForWindowsAccounts, TokenImpersonationLevel impersonationLevel, bool allowNtlm) result = (null, NFTransportDefaults.ExtractGroupsForWindowsAccounts, TokenImpersonationLevel.Identification, ConnectionOrientedTransportDefaults.AllowNtlm); if (tokenProvider != null) { SspiSecurityToken token = await WindowsStreamTransportSecurityHelpers.GetTokenAsync<SspiSecurityToken>(tokenProvider, timeout); if (token != null) { result.extractGroupsForWindowsAccounts = token.ExtractGroupsForWindowsAccounts; result.impersonationLevel = token.ImpersonationLevel; result.allowNtlm = token.AllowNtlm; if (token.NetworkCredential != null) { result.credential = token.NetworkCredential; SecurityUtils.FixNetworkCredential(ref result.credential); } } } // Initialize to the default value if no token provided. A partial trust app should not have access to the // default network credentials but should be able to provide credentials. The DefaultNetworkCredentials // getter will throw under partial trust. if (result.credential == null) { result.credential = CredentialCache.DefaultNetworkCredentials; } return result; } internal static SecurityTokenRequirement CreateSspiTokenRequirement(EndpointAddress target, Uri via, string transportScheme) { InitiatorServiceModelSecurityTokenRequirement sspiTokenRequirement = new InitiatorServiceModelSecurityTokenRequirement(); sspiTokenRequirement.TokenType = ServiceModelSecurityTokenTypes.SspiCredential; sspiTokenRequirement.RequireCryptographicToken = false; sspiTokenRequirement.TransportScheme = transportScheme; sspiTokenRequirement.TargetAddress = target; sspiTokenRequirement.Via = via; return sspiTokenRequirement; } public static SecurityTokenProvider GetSspiTokenProvider( SecurityTokenManager tokenManager, EndpointAddress target, Uri via, string transportScheme) { return tokenManager?.CreateSecurityTokenProvider(CreateSspiTokenRequirement(target, via, transportScheme)); } private static async Task<T> GetTokenAsync<T>(SecurityTokenProvider tokenProvider, TimeSpan timeout) where T : SecurityToken { SecurityToken result = await tokenProvider.GetTokenAsync(timeout); if ((result != null) && !(result is T)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format( SR.InvalidTokenProvided, tokenProvider.GetType(), typeof(T)))); } return result as T; } public static Uri GetListenUri(Uri baseAddress, string relativeAddress) { Uri fullUri = baseAddress; // Ensure that baseAddress Path does end with a slash if we have a relative address if (!string.IsNullOrEmpty(relativeAddress)) { if (!baseAddress.AbsolutePath.EndsWith("/", StringComparison.Ordinal)) { UriBuilder uriBuilder = new UriBuilder(baseAddress); FixIpv6Hostname(uriBuilder, baseAddress); uriBuilder.Path = uriBuilder.Path + "/"; baseAddress = uriBuilder.Uri; } fullUri = new Uri(baseAddress, relativeAddress); } return fullUri; } // Originally: TcpChannelListener.FixIpv6Hostname private static void FixIpv6Hostname(UriBuilder uriBuilder, Uri originalUri) { if (originalUri.HostNameType == UriHostNameType.IPv6) { string ipv6Host = originalUri.DnsSafeHost; uriBuilder.Host = string.Concat("[", ipv6Host, "]"); } } } }