| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System; |
| | | 5 | | using System.Collections.Generic; |
| | | 6 | | using System.Collections.ObjectModel; |
| | | 7 | | using System.Net; |
| | | 8 | | using System.Security.Authentication.ExtendedProtection; |
| | | 9 | | using CoreWCF.Channels; |
| | | 10 | | using CoreWCF.Description; |
| | | 11 | | using CoreWCF.Dispatcher; |
| | | 12 | | using CoreWCF.IdentityModel.Selectors; |
| | | 13 | | using CoreWCF.IdentityModel.Tokens; |
| | | 14 | | using CoreWCF.Security.Tokens; |
| | | 15 | | |
| | | 16 | | namespace CoreWCF.Security |
| | | 17 | | { |
| | | 18 | | public class ServiceCredentialsSecurityTokenManager : SecurityTokenManager, IEndpointIdentityProvider |
| | | 19 | | { |
| | 72 | 20 | | public ServiceCredentialsSecurityTokenManager(ServiceCredentials parent) |
| | | 21 | | { |
| | 72 | 22 | | ServiceCredentials = parent ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(paren |
| | 72 | 23 | | } |
| | | 24 | | |
| | 248 | 25 | | public ServiceCredentials ServiceCredentials { get; } |
| | | 26 | | |
| | | 27 | | public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version) |
| | | 28 | | { |
| | 76 | 29 | | if (version == null) |
| | | 30 | | { |
| | 0 | 31 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(version)); |
| | | 32 | | } |
| | 76 | 33 | | if (version is MessageSecurityTokenVersion wsVersion) |
| | | 34 | | { |
| | 76 | 35 | | SamlSerializer samlSerializer = null; |
| | | 36 | | //TODO this will be implemented when we add WS-Federation support |
| | | 37 | | //if (parent.IssuedTokenAuthentication != null) |
| | | 38 | | // samlSerializer = parent.IssuedTokenAuthentication.SamlSerializer; |
| | | 39 | | //else |
| | | 40 | | // samlSerializer = new SamlSerializer(); |
| | | 41 | | |
| | 76 | 42 | | return new WSSecurityTokenSerializer(wsVersion.SecurityVersion, wsVersion.TrustVersion, wsVersion.Secure |
| | | 43 | | } |
| | | 44 | | else |
| | | 45 | | { |
| | 0 | 46 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.Format(SR.Securit |
| | | 47 | | } |
| | | 48 | | } |
| | | 49 | | |
| | | 50 | | protected SecurityTokenAuthenticator CreateSecureConversationTokenAuthenticator(RecipientServiceModelSecurityTok |
| | | 51 | | { |
| | 22 | 52 | | SecurityBindingElement securityBindingElement = recipientRequirement.SecurityBindingElement; |
| | 22 | 53 | | if (securityBindingElement == null) |
| | | 54 | | { |
| | 0 | 55 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.Format(SR.TokenAuthenticatorRequiresSecu |
| | | 56 | | } |
| | | 57 | | |
| | 22 | 58 | | bool flag = !recipientRequirement.SupportSecurityContextCancellation; |
| | 22 | 59 | | LocalServiceSecuritySettings localServiceSettings = securityBindingElement.LocalServiceSettings; |
| | 22 | 60 | | IMessageFilterTable<EndpointAddress> propertyOrDefault = recipientRequirement.GetPropertyOrDefault<IMessageF |
| | 22 | 61 | | if (!flag) |
| | | 62 | | { |
| | 22 | 63 | | sctResolver = (SecurityTokenResolver)new SecurityContextSecurityTokenResolver(int.MaxValue, false); |
| | 22 | 64 | | return (SecurityTokenAuthenticator)new SecuritySessionSecurityTokenAuthenticator() |
| | 22 | 65 | | { |
| | 22 | 66 | | BootstrapSecurityBindingElement = SecurityUtils.GetIssuerSecurityBindingElement((ServiceModelSecurit |
| | 22 | 67 | | IssuedSecurityTokenParameters = recipientRequirement.GetProperty<SecurityTokenParameters>(ServiceMod |
| | 22 | 68 | | IssuedTokenCache = (ISecurityContextSecurityTokenCache)sctResolver, |
| | 22 | 69 | | IssuerBindingContext = recipientRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenReq |
| | 22 | 70 | | KeyEntropyMode = securityBindingElement.KeyEntropyMode, |
| | 22 | 71 | | ListenUri = recipientRequirement.ListenUri, |
| | 22 | 72 | | SecurityAlgorithmSuite = recipientRequirement.SecurityAlgorithmSuite, |
| | 22 | 73 | | SessionTokenLifetime = TimeSpan.MaxValue, |
| | 22 | 74 | | KeyRenewalInterval = securityBindingElement.LocalServiceSettings.SessionKeyRenewalInterval, |
| | 22 | 75 | | StandardsManager = SecurityUtils.CreateSecurityStandardsManager((SecurityTokenRequirement)recipientR |
| | 22 | 76 | | EndpointFilterTable = propertyOrDefault, |
| | 22 | 77 | | MaximumConcurrentNegotiations = localServiceSettings.MaxStatefulNegotiations, |
| | 22 | 78 | | NegotiationTimeout = localServiceSettings.NegotiationTimeout, |
| | 22 | 79 | | PreserveBootstrapTokens = preserveBootstrapTokens |
| | 22 | 80 | | }; |
| | | 81 | | } |
| | 0 | 82 | | throw new NotImplementedException(); |
| | | 83 | | /* |
| | | 84 | | sctResolver = (SecurityTokenResolver)new SecurityContextSecurityTokenResolver(localServiceSettings.MaxCached |
| | | 85 | | AcceleratedTokenAuthenticator tokenAuthenticator = new AcceleratedTokenAuthenticator(); |
| | | 86 | | tokenAuthenticator.BootstrapSecurityBindingElement = SecurityUtils.GetIssuerSecurityBindingElement((ServiceM |
| | | 87 | | tokenAuthenticator.KeyEntropyMode = securityBindingElement.KeyEntropyMode; |
| | | 88 | | tokenAuthenticator.EncryptStateInServiceToken = true; |
| | | 89 | | tokenAuthenticator.IssuedSecurityTokenParameters = recipientRequirement.GetProperty<SecurityTokenParameters> |
| | | 90 | | tokenAuthenticator.IssuedTokenCache = (ISecurityContextSecurityTokenCache)sctResolver; |
| | | 91 | | tokenAuthenticator.IssuerBindingContext = recipientRequirement.GetProperty<BindingContext>(ServiceModelSecur |
| | | 92 | | tokenAuthenticator.ListenUri = recipientRequirement.ListenUri; |
| | | 93 | | tokenAuthenticator.SecurityAlgorithmSuite = recipientRequirement.SecurityAlgorithmSuite; |
| | | 94 | | tokenAuthenticator.StandardsManager = SecurityUtils.CreateSecurityStandardsManager((SecurityTokenRequirement |
| | | 95 | | tokenAuthenticator.SecurityStateEncoder = this.parent.SecureConversationAuthentication.SecurityStateEncoder; |
| | | 96 | | tokenAuthenticator.KnownTypes = (IList<System.Type>)this.parent.SecureConversationAuthentication.SecurityCon |
| | | 97 | | tokenAuthenticator.PreserveBootstrapTokens = preserveBootstrapTokens; |
| | | 98 | | tokenAuthenticator.MaximumCachedNegotiationState = localServiceSettings.MaxStatefulNegotiations; |
| | | 99 | | tokenAuthenticator.NegotiationTimeout = localServiceSettings.NegotiationTimeout; |
| | | 100 | | tokenAuthenticator.ServiceTokenLifetime = localServiceSettings.IssuedCookieLifetime; |
| | | 101 | | tokenAuthenticator.MaximumConcurrentNegotiations = localServiceSettings.MaxStatefulNegotiations; |
| | | 102 | | // tokenAuthenticator.AuditLogLocation = recipientRequirement.AuditLogLocation; |
| | | 103 | | // tokenAuthenticator.SuppressAuditFailure = recipientRequirement.SuppressAuditFailure; |
| | | 104 | | // tokenAuthenticator.MessageAuthenticationAuditLevel = recipientRequirement.MessageAuthenticationAuditLevel; |
| | | 105 | | tokenAuthenticator.EndpointFilterTable = propertyOrDefault; |
| | | 106 | | return (SecurityTokenAuthenticator)tokenAuthenticator;*/ |
| | | 107 | | |
| | | 108 | | } |
| | | 109 | | |
| | | 110 | | private SecurityTokenAuthenticator CreateSpnegoSecurityTokenAuthenticator(RecipientServiceModelSecurityTokenRequ |
| | | 111 | | { |
| | | 112 | | |
| | 1 | 113 | | SecurityBindingElement securityBindingElement = recipientRequirement.SecurityBindingElement; |
| | 1 | 114 | | if (securityBindingElement == null) |
| | | 115 | | { |
| | 0 | 116 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.Format(SR.TokenAuthenticatorRequiresSecu |
| | | 117 | | } |
| | 1 | 118 | | bool isCookieMode = !recipientRequirement.SupportSecurityContextCancellation; |
| | 1 | 119 | | LocalServiceSecuritySettings localServiceSettings = securityBindingElement.LocalServiceSettings; |
| | 1 | 120 | | sctResolver = new SecurityContextSecurityTokenResolver(localServiceSettings.MaxCachedCookies, true); |
| | 1 | 121 | | recipientRequirement.TryGetProperty<ExtendedProtectionPolicy>(ServiceModelSecurityTokenRequirement.ExtendedP |
| | | 122 | | |
| | 1 | 123 | | SpnegoTokenAuthenticator authenticator = new SpnegoTokenAuthenticator |
| | 1 | 124 | | { |
| | 1 | 125 | | ExtendedProtectionPolicy = null, |
| | 1 | 126 | | AllowUnauthenticatedCallers = ServiceCredentials.WindowsAuthentication.AllowAnonymousLogons, |
| | 1 | 127 | | ExtractGroupsForWindowsAccounts = ServiceCredentials.WindowsAuthentication.IncludeWindowsGroups, |
| | 1 | 128 | | IsClientAnonymous = false, |
| | 1 | 129 | | EncryptStateInServiceToken = isCookieMode, |
| | 1 | 130 | | IssuedSecurityTokenParameters = recipientRequirement.GetProperty<SecurityTokenParameters>(ServiceModelSe |
| | 1 | 131 | | IssuedTokenCache = (ISecurityContextSecurityTokenCache)sctResolver, |
| | 1 | 132 | | IssuerBindingContext = recipientRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequire |
| | 1 | 133 | | ListenUri = recipientRequirement.ListenUri, |
| | 1 | 134 | | SecurityAlgorithmSuite = recipientRequirement.SecurityAlgorithmSuite, |
| | 1 | 135 | | StandardsManager = SecurityUtils.CreateSecurityStandardsManager(recipientRequirement, this), |
| | 1 | 136 | | SecurityStateEncoder = ServiceCredentials.SecureConversationAuthentication.SecurityStateEncoder, |
| | 1 | 137 | | KnownTypes = ServiceCredentials.SecureConversationAuthentication.SecurityContextClaimTypes, |
| | 1 | 138 | | LdapSettings = ServiceCredentials.WindowsAuthentication.LdapSetting |
| | 1 | 139 | | }; |
| | | 140 | | // if the SPNEGO is being done in mixed-mode, the nego blobs are from an anonymous client and so there size |
| | 1 | 141 | | if (securityBindingElement is TransportSecurityBindingElement) |
| | | 142 | | { |
| | 1 | 143 | | authenticator.MaxMessageSize = SecurityUtils.GetMaxNegotiationBufferSize(authenticator.IssuerBindingCont |
| | | 144 | | } |
| | | 145 | | |
| | | 146 | | // local security quotas |
| | 1 | 147 | | authenticator.MaximumCachedNegotiationState = localServiceSettings.MaxStatefulNegotiations; |
| | 1 | 148 | | authenticator.NegotiationTimeout = localServiceSettings.NegotiationTimeout; |
| | 1 | 149 | | authenticator.ServiceTokenLifetime = localServiceSettings.IssuedCookieLifetime; |
| | 1 | 150 | | authenticator.MaximumConcurrentNegotiations = localServiceSettings.MaxStatefulNegotiations; |
| | | 151 | | |
| | | 152 | | // audit settings |
| | | 153 | | //authenticator.AuditLogLocation = recipientRequirement.AuditLogLocation; |
| | | 154 | | //authenticator.SuppressAuditFailure = recipientRequirement.SuppressAuditFailure; |
| | | 155 | | //authenticator.MessageAuthenticationAuditLevel = recipientRequirement.MessageAuthenticationAuditLevel; |
| | 1 | 156 | | return authenticator; |
| | | 157 | | } |
| | | 158 | | |
| | | 159 | | private SecurityTokenAuthenticator CreateTlsnegoClientX509TokenAuthenticator(RecipientServiceModelSecurityTokenR |
| | | 160 | | { |
| | | 161 | | //throw new PlatformNotSupportedException("TlsnegoClientX509Token"); |
| | 0 | 162 | | RecipientServiceModelSecurityTokenRequirement clientX509Requirement = new RecipientServiceModelSecurityToken |
| | 0 | 163 | | { |
| | 0 | 164 | | TokenType = SecurityTokenTypes.X509Certificate, |
| | 0 | 165 | | KeyUsage = SecurityKeyUsage.Signature, |
| | 0 | 166 | | ListenUri = recipientRequirement.ListenUri, |
| | 0 | 167 | | KeyType = SecurityKeyType.AsymmetricKey, |
| | 0 | 168 | | SecurityBindingElement = recipientRequirement.SecurityBindingElement |
| | 0 | 169 | | }; |
| | 0 | 170 | | return CreateSecurityTokenAuthenticator(clientX509Requirement, out _); |
| | | 171 | | } |
| | | 172 | | |
| | | 173 | | private SecurityTokenProvider CreateTlsnegoServerX509TokenProvider(RecipientServiceModelSecurityTokenRequirement |
| | | 174 | | { |
| | | 175 | | //throw new PlatformNotSupportedException("TlsnegoServerX509Token"); |
| | 0 | 176 | | RecipientServiceModelSecurityTokenRequirement serverX509Requirement = new RecipientServiceModelSecurityToken |
| | 0 | 177 | | { |
| | 0 | 178 | | TokenType = SecurityTokenTypes.X509Certificate, |
| | 0 | 179 | | KeyUsage = SecurityKeyUsage.Exchange, |
| | 0 | 180 | | ListenUri = recipientRequirement.ListenUri, |
| | 0 | 181 | | KeyType = SecurityKeyType.AsymmetricKey, |
| | 0 | 182 | | SecurityBindingElement = recipientRequirement.SecurityBindingElement |
| | 0 | 183 | | }; |
| | 0 | 184 | | return CreateSecurityTokenProvider(serverX509Requirement); |
| | | 185 | | } |
| | | 186 | | |
| | | 187 | | private SecurityTokenAuthenticator CreateTlsnegoSecurityTokenAuthenticator(RecipientServiceModelSecurityTokenReq |
| | | 188 | | { |
| | 0 | 189 | | throw new PlatformNotSupportedException("TlsnegoSecurityToken"); |
| | | 190 | | /* |
| | | 191 | | SecurityBindingElement securityBindingElement = recipientRequirement.SecurityBindingElement; |
| | | 192 | | if (securityBindingElement == null) |
| | | 193 | | { |
| | | 194 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.Format(SR.TokenAuthenticatorRequiresSecu |
| | | 195 | | } |
| | | 196 | | bool isCookieMode = !recipientRequirement.SupportSecurityContextCancellation; |
| | | 197 | | LocalServiceSecuritySettings localServiceSettings = securityBindingElement.LocalServiceSettings; |
| | | 198 | | sctResolver = new SecurityContextSecurityTokenResolver(localServiceSettings.MaxCachedCookies, true); |
| | | 199 | | |
| | | 200 | | TlsnegoTokenAuthenticator authenticator = new TlsnegoTokenAuthenticator(); |
| | | 201 | | authenticator.IsClientAnonymous = !requireClientCertificate; |
| | | 202 | | if (requireClientCertificate) |
| | | 203 | | { |
| | | 204 | | authenticator.ClientTokenAuthenticator = this.CreateTlsnegoClientX509TokenAuthenticator(recipientRequire |
| | | 205 | | authenticator.MapCertificateToWindowsAccount = this.ServiceCredentials.ClientCertificate.Authentication. |
| | | 206 | | } |
| | | 207 | | authenticator.EncryptStateInServiceToken = isCookieMode; |
| | | 208 | | authenticator.IssuedSecurityTokenParameters = recipientRequirement.GetProperty<SecurityTokenParameters>(Serv |
| | | 209 | | authenticator.IssuedTokenCache = (ISecurityContextSecurityTokenCache)sctResolver; |
| | | 210 | | authenticator.IssuerBindingContext = recipientRequirement.GetProperty<BindingContext>(ServiceModelSecurityTo |
| | | 211 | | authenticator.ListenUri = recipientRequirement.ListenUri; |
| | | 212 | | authenticator.SecurityAlgorithmSuite = recipientRequirement.SecurityAlgorithmSuite; |
| | | 213 | | authenticator.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(recipientRequirement, this); |
| | | 214 | | authenticator.SecurityStateEncoder = parent.SecureConversationAuthentication.SecurityStateEncoder; |
| | | 215 | | authenticator.KnownTypes = parent.SecureConversationAuthentication.SecurityContextClaimTypes; |
| | | 216 | | authenticator.ServerTokenProvider = CreateTlsnegoServerX509TokenProvider(recipientRequirement); |
| | | 217 | | // local security quotas |
| | | 218 | | authenticator.MaximumCachedNegotiationState = localServiceSettings.MaxStatefulNegotiations; |
| | | 219 | | authenticator.NegotiationTimeout = localServiceSettings.NegotiationTimeout; |
| | | 220 | | authenticator.ServiceTokenLifetime = localServiceSettings.IssuedCookieLifetime; |
| | | 221 | | authenticator.MaximumConcurrentNegotiations = localServiceSettings.MaxStatefulNegotiations; |
| | | 222 | | // if the TLSNEGO is being done in mixed-mode, the nego blobs are from an anonymous client and so there size |
| | | 223 | | if (securityBindingElement is TransportSecurityBindingElement) |
| | | 224 | | { |
| | | 225 | | authenticator.MaxMessageSize = SecurityUtils.GetMaxNegotiationBufferSize(authenticator.IssuerBindingCont |
| | | 226 | | } |
| | | 227 | | // audit settings |
| | | 228 | | // authenticator.AuditLogLocation = recipientRequirement.AuditLogLocation; |
| | | 229 | | // authenticator.SuppressAuditFailure = recipientRequirement.SuppressAuditFailure; |
| | | 230 | | // authenticator.MessageAuthenticationAuditLevel = recipientRequirement.MessageAuthenticationAuditLevel; |
| | | 231 | | return authenticator;*/ |
| | | 232 | | } |
| | | 233 | | |
| | | 234 | | private X509SecurityTokenAuthenticator CreateClientX509TokenAuthenticator() |
| | | 235 | | { |
| | 16 | 236 | | X509ClientCertificateAuthentication authentication = ServiceCredentials.ClientCertificate.Authentication; |
| | 16 | 237 | | return new X509SecurityTokenAuthenticator(authentication.GetCertificateValidator(), authentication.MapClient |
| | | 238 | | } |
| | | 239 | | |
| | | 240 | | private SamlSecurityTokenAuthenticator CreateSamlTokenAuthenticator(RecipientServiceModelSecurityTokenRequiremen |
| | | 241 | | { |
| | 0 | 242 | | if (recipientRequirement == null) |
| | 0 | 243 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(recipientRequirement)); |
| | | 244 | | |
| | 0 | 245 | | Collection<SecurityToken> outOfBandTokens = new Collection<SecurityToken>(); |
| | 0 | 246 | | var parent = ServiceCredentials; |
| | 0 | 247 | | if (parent.ServiceCertificate.Certificate != null) |
| | | 248 | | { |
| | 0 | 249 | | outOfBandTokens.Add(new X509SecurityToken(parent.ServiceCertificate.Certificate)); |
| | | 250 | | } |
| | 0 | 251 | | List<SecurityTokenAuthenticator> supportingAuthenticators = new List<SecurityTokenAuthenticator>(); |
| | 0 | 252 | | if ((parent.IssuedTokenAuthentication.KnownCertificates != null) && (parent.IssuedTokenAuthentication.KnownC |
| | | 253 | | { |
| | 0 | 254 | | for (int i = 0; i < parent.IssuedTokenAuthentication.KnownCertificates.Count; ++i) |
| | | 255 | | { |
| | 0 | 256 | | outOfBandTokens.Add(new X509SecurityToken(parent.IssuedTokenAuthentication.KnownCertificates[i])); |
| | | 257 | | } |
| | | 258 | | } |
| | | 259 | | |
| | 0 | 260 | | X509CertificateValidator validator = parent.IssuedTokenAuthentication.GetCertificateValidator(); |
| | 0 | 261 | | supportingAuthenticators.Add(new X509SecurityTokenAuthenticator(validator)); |
| | | 262 | | |
| | 0 | 263 | | if (parent.IssuedTokenAuthentication.AllowUntrustedRsaIssuers) |
| | | 264 | | { |
| | 0 | 265 | | supportingAuthenticators.Add(new RsaSecurityTokenAuthenticator()); |
| | | 266 | | } |
| | | 267 | | |
| | 0 | 268 | | outOfBandTokenResolver = (outOfBandTokens.Count > 0) ? SecurityTokenResolver.CreateDefaultSecurityTokenResol |
| | | 269 | | |
| | | 270 | | SamlSecurityTokenAuthenticator ssta; |
| | | 271 | | |
| | 0 | 272 | | if ((recipientRequirement.SecurityBindingElement == null) || (recipientRequirement.SecurityBindingElement.Lo |
| | | 273 | | { |
| | 0 | 274 | | ssta = new SamlSecurityTokenAuthenticator(supportingAuthenticators); |
| | | 275 | | } |
| | | 276 | | else |
| | | 277 | | { |
| | 0 | 278 | | ssta = new SamlSecurityTokenAuthenticator(supportingAuthenticators, recipientRequirement.SecurityBinding |
| | | 279 | | } |
| | | 280 | | |
| | | 281 | | // set audience uri restrictions |
| | 0 | 282 | | ssta.AudienceUriMode = parent.IssuedTokenAuthentication.AudienceUriMode; |
| | 0 | 283 | | IList<string> allowedAudienceUris = ssta.AllowedAudienceUris; |
| | 0 | 284 | | if (parent.IssuedTokenAuthentication.AllowedAudienceUris != null) |
| | | 285 | | { |
| | 0 | 286 | | for (int i = 0; i < parent.IssuedTokenAuthentication.AllowedAudienceUris.Count; i++) |
| | 0 | 287 | | allowedAudienceUris.Add(parent.IssuedTokenAuthentication.AllowedAudienceUris[i]); |
| | | 288 | | } |
| | | 289 | | |
| | 0 | 290 | | if (recipientRequirement.ListenUri != null) |
| | | 291 | | { |
| | 0 | 292 | | allowedAudienceUris.Add(recipientRequirement.ListenUri.AbsoluteUri); |
| | | 293 | | } |
| | | 294 | | |
| | 0 | 295 | | return ssta; |
| | | 296 | | } |
| | | 297 | | |
| | | 298 | | private X509SecurityTokenProvider CreateServerX509TokenProvider() |
| | | 299 | | { |
| | 5 | 300 | | if (ServiceCredentials.ServiceCertificate.Certificate == null) |
| | | 301 | | { |
| | 0 | 302 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.ServiceCertif |
| | | 303 | | } |
| | 5 | 304 | | SecurityUtils.EnsureCertificateCanDoKeyExchange(ServiceCredentials.ServiceCertificate.Certificate); |
| | 5 | 305 | | return new ServiceX509SecurityTokenProvider(ServiceCredentials.ServiceCertificate.Certificate); |
| | | 306 | | } |
| | | 307 | | |
| | | 308 | | protected bool IsIssuedSecurityTokenRequirement(SecurityTokenRequirement requirement) |
| | | 309 | | { |
| | 0 | 310 | | return (requirement != null && requirement.Properties.ContainsKey(ServiceModelSecurityTokenRequirement.Issue |
| | | 311 | | } |
| | | 312 | | |
| | | 313 | | public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequir |
| | | 314 | | { |
| | 54 | 315 | | if (tokenRequirement == null) |
| | | 316 | | { |
| | 0 | 317 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(tokenRequirement)); |
| | | 318 | | } |
| | 54 | 319 | | string tokenType = tokenRequirement.TokenType; |
| | 54 | 320 | | outOfBandTokenResolver = null; |
| | 54 | 321 | | SecurityTokenAuthenticator result = null; |
| | 54 | 322 | | if (tokenRequirement is InitiatorServiceModelSecurityTokenRequirement) |
| | | 323 | | { |
| | | 324 | | // this is the uncorrelated duplex case in which the server is asking for |
| | | 325 | | // an authenticator to validate its provisioned client certificate |
| | 0 | 326 | | if (tokenType == SecurityTokenTypes.X509Certificate && tokenRequirement.KeyUsage == SecurityKeyUsage.Exc |
| | | 327 | | { |
| | 0 | 328 | | return new X509SecurityTokenAuthenticator(X509CertificateValidator.None, false); |
| | | 329 | | } |
| | | 330 | | } |
| | | 331 | | |
| | 54 | 332 | | if (!(tokenRequirement is RecipientServiceModelSecurityTokenRequirement recipientRequirement)) |
| | | 333 | | { |
| | 0 | 334 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.Format(SR.Securit |
| | | 335 | | } |
| | 54 | 336 | | if (tokenType == SecurityTokenTypes.X509Certificate) |
| | | 337 | | { |
| | 16 | 338 | | result = CreateClientX509TokenAuthenticator(); |
| | | 339 | | } |
| | 38 | 340 | | else if (tokenType == SecurityTokenTypes.Kerberos) |
| | | 341 | | { |
| | 0 | 342 | | throw new PlatformNotSupportedException("KerberosSecurityTokenAuthenticator"); |
| | | 343 | | //result = new KerberosSecurityTokenAuthenticatorWrapper( |
| | | 344 | | // new KerberosSecurityTokenAuthenticator(parent.WindowsAuthentication.IncludeWindowsGroups)); |
| | | 345 | | } |
| | 38 | 346 | | else if (tokenType == SecurityTokenTypes.UserName) |
| | | 347 | | { |
| | 15 | 348 | | if (ServiceCredentials.UserNameAuthentication.UserNamePasswordValidationMode == UserNamePasswordValidati |
| | | 349 | | { |
| | 0 | 350 | | throw new PlatformNotSupportedException("UserNamePasswordValidationMode.Windows"); |
| | | 351 | | //if (parent.UserNameAuthentication.CacheLogonTokens) |
| | | 352 | | //{ |
| | | 353 | | // result = new WindowsUserNameCachingSecurityTokenAuthenticator(parent.UserNameAuthentication.In |
| | | 354 | | // parent.UserNameAuthentication.MaxCachedLogonTokens, parent.UserNameAuthentication.CachedLo |
| | | 355 | | //} |
| | | 356 | | //else |
| | | 357 | | //{ |
| | | 358 | | // result = new WindowsUserNameSecurityTokenAuthenticator(parent.UserNameAuthentication.IncludeWi |
| | | 359 | | //} |
| | | 360 | | } |
| | | 361 | | else |
| | | 362 | | { |
| | 15 | 363 | | result = new CustomUserNameSecurityTokenAuthenticator(ServiceCredentials.UserNameAuthentication.GetU |
| | | 364 | | } |
| | | 365 | | } |
| | 23 | 366 | | else if (tokenType == SecurityTokenTypes.Rsa) |
| | | 367 | | { |
| | 0 | 368 | | result = new RsaSecurityTokenAuthenticator(); |
| | | 369 | | } |
| | 23 | 370 | | else if (tokenType == ServiceModelSecurityTokenTypes.AnonymousSslnego) |
| | | 371 | | { |
| | 0 | 372 | | throw new NotSupportedException(); |
| | | 373 | | // result = CreateTlsnegoSecurityTokenAuthenticator(recipientRequirement, false, out outOfBandTokenResolv |
| | | 374 | | } |
| | 23 | 375 | | else if (tokenType == ServiceModelSecurityTokenTypes.MutualSslnego) |
| | | 376 | | { |
| | 0 | 377 | | throw new NotSupportedException(); |
| | | 378 | | // result = CreateTlsnegoSecurityTokenAuthenticator(recipientRequirement, true, out outOfBandTokenResol |
| | | 379 | | } |
| | 23 | 380 | | else if (tokenType == ServiceModelSecurityTokenTypes.Spnego) |
| | | 381 | | { |
| | 1 | 382 | | result = CreateSpnegoSecurityTokenAuthenticator(recipientRequirement, out outOfBandTokenResolver); |
| | | 383 | | } |
| | 22 | 384 | | else if (tokenType == ServiceModelSecurityTokenTypes.SecureConversation) |
| | | 385 | | { |
| | 22 | 386 | | result = CreateSecureConversationTokenAuthenticator(recipientRequirement, false, out outOfBandTokenResol |
| | | 387 | | } |
| | 0 | 388 | | else if ((tokenType == SecurityTokenTypes.Saml) |
| | 0 | 389 | | || (tokenType == SecurityXXX2005Strings.SamlTokenType) |
| | 0 | 390 | | || (tokenType == SecurityJan2004Strings.SamlUri) |
| | 0 | 391 | | || (tokenType == null && IsIssuedSecurityTokenRequirement(recipientRequirement))) |
| | | 392 | | { |
| | 0 | 393 | | result = CreateSamlTokenAuthenticator(recipientRequirement, out outOfBandTokenResolver); |
| | | 394 | | } |
| | | 395 | | |
| | 54 | 396 | | if (result == null) |
| | | 397 | | { |
| | 0 | 398 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.Format(SR.Securit |
| | | 399 | | } |
| | | 400 | | |
| | 54 | 401 | | return result; |
| | | 402 | | } |
| | | 403 | | |
| | | 404 | | private SecurityTokenProvider CreateLocalSecurityTokenProvider(RecipientServiceModelSecurityTokenRequirement rec |
| | | 405 | | { |
| | 17 | 406 | | string tokenType = recipientRequirement.TokenType; |
| | 17 | 407 | | SecurityTokenProvider result = null; |
| | 17 | 408 | | if (tokenType == SecurityTokenTypes.X509Certificate) |
| | | 409 | | { |
| | 5 | 410 | | result = CreateServerX509TokenProvider(); |
| | | 411 | | } |
| | 12 | 412 | | else if (tokenType == ServiceModelSecurityTokenTypes.SspiCredential) |
| | | 413 | | { |
| | | 414 | | // if Transport Security, AuthenticationSchemes.Basic will look at parent.UserNameAuthentication setting |
| | 12 | 415 | | bool authenticationSchemeIdentified = recipientRequirement.TryGetProperty<AuthenticationSchemes>(Service |
| | 12 | 416 | | if (authenticationSchemeIdentified && |
| | 12 | 417 | | authenticationScheme.IsSet(AuthenticationSchemes.Basic) && |
| | 12 | 418 | | authenticationScheme.IsNotSet(AuthenticationSchemes.Digest | AuthenticationSchemes.Ntlm | Authentica |
| | | 419 | | { |
| | | 420 | | // create security token provider even when basic and Anonymous are enabled. |
| | 0 | 421 | | result = new SspiSecurityTokenProvider(null, ServiceCredentials.UserNameAuthentication.IncludeWindow |
| | | 422 | | } |
| | | 423 | | else |
| | | 424 | | { |
| | 12 | 425 | | if (authenticationSchemeIdentified && |
| | 12 | 426 | | authenticationScheme.IsSet(AuthenticationSchemes.Basic) && |
| | 12 | 427 | | ServiceCredentials.WindowsAuthentication.IncludeWindowsGroups != ServiceCredentials.UserNameAuthe |
| | | 428 | | { |
| | | 429 | | // Ensure there are no inconsistencies when Basic and (Digest and/or Ntlm and/or Negotiate) are |
| | 0 | 430 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.Format(SR |
| | 0 | 431 | | (AuthenticationSchemes)authenticationScheme - AuthenticationSchemes.Basic, |
| | 0 | 432 | | ServiceCredentials.UserNameAuthentication.IncludeWindowsGroups, |
| | 0 | 433 | | ServiceCredentials.WindowsAuthentication.IncludeWindowsGroups))); |
| | | 434 | | } |
| | | 435 | | |
| | 12 | 436 | | result = new SspiSecurityTokenProvider(null, ServiceCredentials.WindowsAuthentication.IncludeWindows |
| | | 437 | | } |
| | | 438 | | } |
| | 17 | 439 | | return result; |
| | | 440 | | } |
| | | 441 | | |
| | | 442 | | private SecurityTokenProvider CreateUncorrelatedDuplexSecurityTokenProvider(InitiatorServiceModelSecurityTokenRe |
| | | 443 | | { |
| | 0 | 444 | | string tokenType = initiatorRequirement.TokenType; |
| | 0 | 445 | | SecurityTokenProvider result = null; |
| | 0 | 446 | | if (tokenType == SecurityTokenTypes.X509Certificate) |
| | | 447 | | { |
| | 0 | 448 | | SecurityKeyUsage keyUsage = initiatorRequirement.KeyUsage; |
| | 0 | 449 | | if (keyUsage == SecurityKeyUsage.Exchange) |
| | | 450 | | { |
| | 0 | 451 | | if (ServiceCredentials.ClientCertificate.Certificate == null) |
| | | 452 | | { |
| | 0 | 453 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Clien |
| | | 454 | | } |
| | | 455 | | |
| | 0 | 456 | | result = new X509SecurityTokenProvider(ServiceCredentials.ClientCertificate.Certificate); |
| | | 457 | | } |
| | | 458 | | else |
| | | 459 | | { |
| | | 460 | | // this is a request for the server's own cert for signing |
| | 0 | 461 | | result = CreateServerX509TokenProvider(); |
| | | 462 | | } |
| | | 463 | | } |
| | 0 | 464 | | return result; |
| | | 465 | | } |
| | | 466 | | |
| | | 467 | | public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement requirement) |
| | | 468 | | { |
| | 17 | 469 | | if (requirement == null) |
| | | 470 | | { |
| | 0 | 471 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(requirement)); |
| | | 472 | | } |
| | | 473 | | |
| | 17 | 474 | | SecurityTokenProvider result = null; |
| | 17 | 475 | | if (requirement is RecipientServiceModelSecurityTokenRequirement recipientRequirement) |
| | | 476 | | { |
| | 17 | 477 | | result = CreateLocalSecurityTokenProvider(recipientRequirement); |
| | | 478 | | } |
| | 0 | 479 | | else if (requirement is InitiatorServiceModelSecurityTokenRequirement) |
| | | 480 | | { |
| | 0 | 481 | | result = CreateUncorrelatedDuplexSecurityTokenProvider((InitiatorServiceModelSecurityTokenRequirement)re |
| | | 482 | | } |
| | | 483 | | |
| | 17 | 484 | | if (result == null) |
| | | 485 | | { |
| | 0 | 486 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.Format(SR.Securit |
| | | 487 | | } |
| | 17 | 488 | | return result; |
| | | 489 | | } |
| | | 490 | | |
| | | 491 | | public virtual EndpointIdentity GetIdentityOfSelf(SecurityTokenRequirement tokenRequirement) |
| | | 492 | | { |
| | 0 | 493 | | if (tokenRequirement == null) |
| | | 494 | | { |
| | 0 | 495 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(tokenRequirement)); |
| | | 496 | | } |
| | 0 | 497 | | if (tokenRequirement is RecipientServiceModelSecurityTokenRequirement) |
| | | 498 | | { |
| | 0 | 499 | | string tokenType = tokenRequirement.TokenType; |
| | 0 | 500 | | if (tokenType == SecurityTokenTypes.X509Certificate |
| | 0 | 501 | | || tokenType == ServiceModelSecurityTokenTypes.AnonymousSslnego |
| | 0 | 502 | | || tokenType == ServiceModelSecurityTokenTypes.MutualSslnego) |
| | | 503 | | { |
| | 0 | 504 | | if (ServiceCredentials.ServiceCertificate.Certificate != null) |
| | | 505 | | { |
| | 0 | 506 | | return EndpointIdentity.CreateX509CertificateIdentity(ServiceCredentials.ServiceCertificate.Cert |
| | | 507 | | } |
| | | 508 | | } |
| | 0 | 509 | | else if (tokenType == SecurityTokenTypes.Kerberos || tokenType == ServiceModelSecurityTokenTypes.Spnego) |
| | | 510 | | { |
| | | 511 | | // TODO: Add WindowsIdentity support here as it looks like it is doable |
| | 0 | 512 | | throw new PlatformNotSupportedException("WindowsIdentity"); |
| | | 513 | | //return SecurityUtils.CreateWindowsIdentity(); |
| | | 514 | | } |
| | 0 | 515 | | else if (tokenType == ServiceModelSecurityTokenTypes.SecureConversation) |
| | | 516 | | { |
| | 0 | 517 | | throw new PlatformNotSupportedException("SecureConversation"); |
| | | 518 | | //SecurityBindingElement securityBindingElement = ((RecipientServiceModelSecurityTokenRequirement)to |
| | | 519 | | //if (securityBindingElement != null) |
| | | 520 | | //{ |
| | | 521 | | // if (securityBindingElement == null || securityBindingElement is TransportSecurityBindingElemen |
| | | 522 | | // { |
| | | 523 | | // return null; |
| | | 524 | | // } |
| | | 525 | | // SecurityTokenParameters bootstrapProtectionParameters = (securityBindingElement is SymmetricSe |
| | | 526 | | // SecurityTokenRequirement bootstrapRequirement = new RecipientServiceModelSecurityTokenRequirem |
| | | 527 | | // bootstrapProtectionParameters.InitializeSecurityTokenRequirement(bootstrapRequirement); |
| | | 528 | | // return GetIdentityOfSelf(bootstrapRequirement); |
| | | 529 | | //} |
| | | 530 | | } |
| | | 531 | | } |
| | 0 | 532 | | return null; |
| | | 533 | | } |
| | | 534 | | } |
| | | 535 | | } |