| File: System\ServiceModel\Channels\TransportSecurityHelpers.cs | Web Access |
| Project: src\src\System.ServiceModel.Primitives\src\System.ServiceModel.Primitives.csproj (System.ServiceModel.Primitives) |
// 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.IdentityModel.Selectors; using System.IdentityModel.Tokens; using System.Net; using System.Net.Security; using System.Runtime; using System.Security.Principal; using System.ServiceModel.Security; using System.ServiceModel.Security.Tokens; using System.Threading.Tasks; namespace System.ServiceModel.Channels { internal static class TransportSecurityHelpers { // 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); } // core Cred lookup code public static async ValueTask<(NetworkCredential credential, bool extractGroupsForWindowsAccounts, TokenImpersonationLevel impersonationLevel, bool allowNtlm)> GetSspiCredentialCoreAsync( SspiSecurityTokenProvider tokenProvider, TimeSpan timeout) { (NetworkCredential credential, bool extractGroupsForWindowsAccounts, TokenImpersonationLevel impersonationLevel, bool allowNtlm) result = (null, TransportDefaults.ExtractGroupsForWindowsAccounts, TokenImpersonationLevel.Identification, SspiSecurityTokenProvider.DefaultAllowNtlm); if (tokenProvider != null) { SspiSecurityToken token = await TransportSecurityHelpers.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 SspiSecurityTokenProvider GetSspiTokenProvider( SecurityTokenManager tokenManager, EndpointAddress target, Uri via, string transportScheme, AuthenticationSchemes authenticationScheme, ChannelParameterCollection channelParameters) { if (tokenManager != null) { SecurityTokenRequirement sspiRequirement = CreateSspiTokenRequirement(target, via, transportScheme); sspiRequirement.Properties[ServiceModelSecurityTokenRequirement.HttpAuthenticationSchemeProperty] = authenticationScheme; if (channelParameters != null) { sspiRequirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty] = channelParameters; } SspiSecurityTokenProvider tokenProvider = tokenManager.CreateSecurityTokenProvider(sspiRequirement) as SspiSecurityTokenProvider; return tokenProvider; } return null; } public static SecurityTokenProvider GetDigestTokenProvider( SecurityTokenManager tokenManager, EndpointAddress target, Uri via, string transportScheme, AuthenticationSchemes authenticationScheme, ChannelParameterCollection channelParameters) { if (tokenManager != null) { InitiatorServiceModelSecurityTokenRequirement digestTokenRequirement = new InitiatorServiceModelSecurityTokenRequirement(); digestTokenRequirement.TokenType = ServiceModelSecurityTokenTypes.SspiCredential; digestTokenRequirement.TargetAddress = target; digestTokenRequirement.Via = via; digestTokenRequirement.RequireCryptographicToken = false; digestTokenRequirement.TransportScheme = transportScheme; digestTokenRequirement.Properties[ServiceModelSecurityTokenRequirement.HttpAuthenticationSchemeProperty] = authenticationScheme; if (channelParameters != null) { digestTokenRequirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty] = channelParameters; } return tokenManager.CreateSecurityTokenProvider(digestTokenRequirement) as SspiSecurityTokenProvider; } return null; } public static SecurityTokenProvider GetCertificateTokenProvider( SecurityTokenManager tokenManager, EndpointAddress target, Uri via, string transportScheme, ChannelParameterCollection channelParameters) { if (tokenManager != null) { InitiatorServiceModelSecurityTokenRequirement certificateTokenRequirement = new InitiatorServiceModelSecurityTokenRequirement(); certificateTokenRequirement.TokenType = SecurityTokenTypes.X509Certificate; certificateTokenRequirement.TargetAddress = target; certificateTokenRequirement.Via = via; certificateTokenRequirement.RequireCryptographicToken = false; certificateTokenRequirement.TransportScheme = transportScheme; if (channelParameters != null) { certificateTokenRequirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty] = channelParameters; } return tokenManager.CreateSecurityTokenProvider(certificateTokenRequirement); } return null; } 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(SRP.Format( SRP.InvalidTokenProvided, tokenProvider.GetType(), typeof(T)))); } return result as T; } public static async Task<NetworkCredential> GetUserNameCredentialAsync(SecurityTokenProviderContainer tokenProvider, TimeSpan timeout) { NetworkCredential result = null; if (tokenProvider != null && tokenProvider.TokenProvider != null) { UserNameSecurityToken token = await GetTokenAsync<UserNameSecurityToken>(tokenProvider.TokenProvider, timeout); if (token != null) { result = new NetworkCredential(token.UserName, token.Password); } } if (result == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SRP.NoUserNameTokenProvided)); } return result; } public static SecurityTokenProvider GetUserNameTokenProvider( SecurityTokenManager tokenManager, EndpointAddress target, Uri via, string transportScheme, AuthenticationSchemes authenticationScheme, ChannelParameterCollection channelParameters) { SecurityTokenProvider result = null; if (tokenManager != null) { SecurityTokenRequirement usernameRequirement = CreateUserNameTokenRequirement(target, via, transportScheme); usernameRequirement.Properties[ServiceModelSecurityTokenRequirement.HttpAuthenticationSchemeProperty] = authenticationScheme; if (channelParameters != null) { usernameRequirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty] = channelParameters; } result = tokenManager.CreateSecurityTokenProvider(usernameRequirement); } return result; } private static InitiatorServiceModelSecurityTokenRequirement CreateUserNameTokenRequirement( EndpointAddress target, Uri via, string transportScheme) { InitiatorServiceModelSecurityTokenRequirement usernameRequirement = new InitiatorServiceModelSecurityTokenRequirement(); usernameRequirement.RequireCryptographicToken = false; usernameRequirement.TokenType = SecurityTokenTypes.UserName; usernameRequirement.TargetAddress = target; usernameRequirement.Via = via; usernameRequirement.TransportScheme = transportScheme; return usernameRequirement; } } internal static class AuthenticationLevelHelper { internal static string ToString(AuthenticationLevel authenticationLevel) { if (authenticationLevel == AuthenticationLevel.MutualAuthRequested) { return "mutualAuthRequested"; } if (authenticationLevel == AuthenticationLevel.MutualAuthRequired) { return "mutualAuthRequired"; } if (authenticationLevel == AuthenticationLevel.None) { return "none"; } Fx.Assert("unknown authentication level"); return authenticationLevel.ToString(); } } }