| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865 |
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace System.ServiceModel
- {
- using System.Collections.Generic;
- using System.IdentityModel.Selectors;
- using System.IdentityModel.Tokens;
- using System.Net;
- using System.Security.Authentication.ExtendedProtection;
- using System.Security.Cryptography.X509Certificates;
- using System.ServiceModel.Channels;
- using System.ServiceModel.Description;
- using System.ServiceModel.Security;
- using System.ServiceModel.Security.Tokens;
- using System.Xml;
- using System.IdentityModel.Protocols.WSTrust;
- using SafeFreeCredentials = System.IdentityModel.SafeFreeCredentials;
- public class ClientCredentialsSecurityTokenManager : SecurityTokenManager
- {
- ClientCredentials parent;
- public ClientCredentialsSecurityTokenManager(ClientCredentials clientCredentials)
- {
- if (clientCredentials == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("clientCredentials");
- }
- this.parent = clientCredentials;
- }
- public ClientCredentials ClientCredentials
- {
- get { return this.parent; }
- }
- string GetServicePrincipalName(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
- {
- EndpointAddress targetAddress = initiatorRequirement.TargetAddress;
- if (targetAddress == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenRequirementDoesNotSpecifyTargetAddress, initiatorRequirement));
- }
- IdentityVerifier identityVerifier;
- SecurityBindingElement securityBindingElement = initiatorRequirement.SecurityBindingElement;
- if (securityBindingElement != null)
- {
- identityVerifier = securityBindingElement.LocalClientSettings.IdentityVerifier;
- }
- else
- {
- identityVerifier = IdentityVerifier.CreateDefault();
- }
- EndpointIdentity identity;
- identityVerifier.TryGetIdentity(targetAddress, out identity);
- return SecurityUtils.GetSpnFromIdentity(identity, targetAddress);
- }
- SspiSecurityToken GetSpnegoClientCredential(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
- {
- InitiatorServiceModelSecurityTokenRequirement sspiCredentialRequirement = new InitiatorServiceModelSecurityTokenRequirement();
- sspiCredentialRequirement.TargetAddress = initiatorRequirement.TargetAddress;
- sspiCredentialRequirement.TokenType = ServiceModelSecurityTokenTypes.SspiCredential;
- sspiCredentialRequirement.Via = initiatorRequirement.Via;
- sspiCredentialRequirement.RequireCryptographicToken = false;
- sspiCredentialRequirement.SecurityBindingElement = initiatorRequirement.SecurityBindingElement;
- sspiCredentialRequirement.MessageSecurityVersion = initiatorRequirement.MessageSecurityVersion;
- ChannelParameterCollection parameters;
- if (initiatorRequirement.TryGetProperty<ChannelParameterCollection>(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, out parameters))
- {
- sspiCredentialRequirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty] = parameters;
- }
- SecurityTokenProvider sspiTokenProvider = this.CreateSecurityTokenProvider(sspiCredentialRequirement);
- SecurityUtils.OpenTokenProviderIfRequired(sspiTokenProvider, TimeSpan.Zero);
- SspiSecurityToken sspiToken = (SspiSecurityToken) sspiTokenProvider.GetToken(TimeSpan.Zero);
- SecurityUtils.AbortTokenProviderIfRequired(sspiTokenProvider);
- return sspiToken;
- }
- SecurityTokenProvider CreateSpnegoTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
- {
- EndpointAddress targetAddress = initiatorRequirement.TargetAddress;
- if (targetAddress == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenRequirementDoesNotSpecifyTargetAddress, initiatorRequirement));
- }
- SecurityBindingElement securityBindingElement = initiatorRequirement.SecurityBindingElement;
- if (securityBindingElement == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenProviderRequiresSecurityBindingElement, initiatorRequirement));
- }
- SspiIssuanceChannelParameter sspiChannelParameter = GetSspiIssuanceChannelParameter(initiatorRequirement);
- bool negotiateTokenOnOpen = (sspiChannelParameter == null ? true : sspiChannelParameter.GetTokenOnOpen);
- LocalClientSecuritySettings localClientSettings = securityBindingElement.LocalClientSettings;
- BindingContext issuerBindingContext = initiatorRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
- SpnegoTokenProvider spnegoTokenProvider = new SpnegoTokenProvider(sspiChannelParameter != null ? sspiChannelParameter.CredentialsHandle : null, securityBindingElement);
- SspiSecurityToken clientSspiToken = GetSpnegoClientCredential(initiatorRequirement);
- spnegoTokenProvider.ClientCredential = clientSspiToken.NetworkCredential;
- spnegoTokenProvider.IssuerAddress = initiatorRequirement.IssuerAddress;
- spnegoTokenProvider.AllowedImpersonationLevel = parent.Windows.AllowedImpersonationLevel;
- spnegoTokenProvider.AllowNtlm = clientSspiToken.AllowNtlm;
- spnegoTokenProvider.IdentityVerifier = localClientSettings.IdentityVerifier;
- spnegoTokenProvider.SecurityAlgorithmSuite = initiatorRequirement.SecurityAlgorithmSuite;
- // if this is not a supporting token, authenticate the server
- spnegoTokenProvider.AuthenticateServer = !initiatorRequirement.Properties.ContainsKey(ServiceModelSecurityTokenRequirement.SupportingTokenAttachmentModeProperty);
- spnegoTokenProvider.NegotiateTokenOnOpen = negotiateTokenOnOpen;
- spnegoTokenProvider.CacheServiceTokens = negotiateTokenOnOpen || localClientSettings.CacheCookies;
- spnegoTokenProvider.IssuerBindingContext = issuerBindingContext;
- spnegoTokenProvider.MaxServiceTokenCachingTime = localClientSettings.MaxCookieCachingTime;
- spnegoTokenProvider.ServiceTokenValidityThresholdPercentage = localClientSettings.CookieRenewalThresholdPercentage;
- spnegoTokenProvider.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(initiatorRequirement, this);
- spnegoTokenProvider.TargetAddress = targetAddress;
- spnegoTokenProvider.Via = initiatorRequirement.GetPropertyOrDefault<Uri>(InitiatorServiceModelSecurityTokenRequirement.ViaProperty, null);
- spnegoTokenProvider.ApplicationProtectionRequirements = (issuerBindingContext != null) ? issuerBindingContext.BindingParameters.Find<ChannelProtectionRequirements>() : null;
- spnegoTokenProvider.InteractiveNegoExLogonEnabled = this.ClientCredentials.SupportInteractive;
-
- return spnegoTokenProvider;
- }
- SecurityTokenProvider CreateTlsnegoClientX509TokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
- {
- InitiatorServiceModelSecurityTokenRequirement clientX509Requirement = new InitiatorServiceModelSecurityTokenRequirement();
- clientX509Requirement.TokenType = SecurityTokenTypes.X509Certificate;
- clientX509Requirement.TargetAddress = initiatorRequirement.TargetAddress;
- clientX509Requirement.SecurityBindingElement = initiatorRequirement.SecurityBindingElement;
- clientX509Requirement.SecurityAlgorithmSuite = initiatorRequirement.SecurityAlgorithmSuite;
- clientX509Requirement.RequireCryptographicToken = true;
- clientX509Requirement.MessageSecurityVersion = initiatorRequirement.MessageSecurityVersion;
- clientX509Requirement.KeyUsage = SecurityKeyUsage.Signature;
- clientX509Requirement.KeyType = SecurityKeyType.AsymmetricKey;
- clientX509Requirement.Properties[ServiceModelSecurityTokenRequirement.MessageDirectionProperty] = MessageDirection.Output;
- ChannelParameterCollection parameters;
- if (initiatorRequirement.TryGetProperty<ChannelParameterCollection>(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, out parameters))
- {
- clientX509Requirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty] = parameters;
- }
- return this.CreateSecurityTokenProvider(clientX509Requirement);
- }
- SecurityTokenAuthenticator CreateTlsnegoServerX509TokenAuthenticator(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
- {
- InitiatorServiceModelSecurityTokenRequirement serverX509Requirement = new InitiatorServiceModelSecurityTokenRequirement();
- serverX509Requirement.TokenType = SecurityTokenTypes.X509Certificate;
- serverX509Requirement.RequireCryptographicToken = true;
- serverX509Requirement.SecurityBindingElement = initiatorRequirement.SecurityBindingElement;
- serverX509Requirement.MessageSecurityVersion = initiatorRequirement.MessageSecurityVersion;
- serverX509Requirement.KeyUsage = SecurityKeyUsage.Exchange;
- serverX509Requirement.KeyType = SecurityKeyType.AsymmetricKey;
- serverX509Requirement.Properties[ServiceModelSecurityTokenRequirement.MessageDirectionProperty] = MessageDirection.Input;
- ChannelParameterCollection parameters;
- if (initiatorRequirement.TryGetProperty<ChannelParameterCollection>(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, out parameters))
- {
- serverX509Requirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty] = parameters;
- }
- SecurityTokenResolver dummy;
- return this.CreateSecurityTokenAuthenticator(serverX509Requirement, out dummy);
- }
- SspiIssuanceChannelParameter GetSspiIssuanceChannelParameter(SecurityTokenRequirement initiatorRequirement)
- {
- ChannelParameterCollection channelParameters;
- if (initiatorRequirement.TryGetProperty<ChannelParameterCollection>(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, out channelParameters))
- {
- if (channelParameters != null)
- {
- for (int i = 0; i < channelParameters.Count; ++i)
- {
- if (channelParameters[i] is SspiIssuanceChannelParameter)
- {
- return (SspiIssuanceChannelParameter)channelParameters[i];
- }
- }
- }
- }
- return null;
- }
- SecurityTokenProvider CreateTlsnegoTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement, bool requireClientCertificate)
- {
- EndpointAddress targetAddress = initiatorRequirement.TargetAddress;
- if (targetAddress == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenRequirementDoesNotSpecifyTargetAddress, initiatorRequirement));
- }
- SecurityBindingElement securityBindingElement = initiatorRequirement.SecurityBindingElement;
- if (securityBindingElement == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenProviderRequiresSecurityBindingElement, initiatorRequirement));
- }
- SspiIssuanceChannelParameter sspiChannelParameter = GetSspiIssuanceChannelParameter(initiatorRequirement);
- bool negotiateTokenOnOpen = sspiChannelParameter != null && sspiChannelParameter.GetTokenOnOpen;
- LocalClientSecuritySettings localClientSettings = securityBindingElement.LocalClientSettings;
- BindingContext issuerBindingContext = initiatorRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
- TlsnegoTokenProvider tlsnegoTokenProvider = new TlsnegoTokenProvider();
- tlsnegoTokenProvider.IssuerAddress = initiatorRequirement.IssuerAddress;
- tlsnegoTokenProvider.NegotiateTokenOnOpen = negotiateTokenOnOpen;
- tlsnegoTokenProvider.CacheServiceTokens = negotiateTokenOnOpen || localClientSettings.CacheCookies;
- if (requireClientCertificate)
- {
- tlsnegoTokenProvider.ClientTokenProvider = this.CreateTlsnegoClientX509TokenProvider(initiatorRequirement);
- }
- tlsnegoTokenProvider.IssuerBindingContext = issuerBindingContext;
- tlsnegoTokenProvider.ApplicationProtectionRequirements = (issuerBindingContext != null) ? issuerBindingContext.BindingParameters.Find<ChannelProtectionRequirements>() : null;
- tlsnegoTokenProvider.MaxServiceTokenCachingTime = localClientSettings.MaxCookieCachingTime;
- tlsnegoTokenProvider.SecurityAlgorithmSuite = initiatorRequirement.SecurityAlgorithmSuite;
- tlsnegoTokenProvider.ServerTokenAuthenticator = this.CreateTlsnegoServerX509TokenAuthenticator(initiatorRequirement);
- tlsnegoTokenProvider.ServiceTokenValidityThresholdPercentage = localClientSettings.CookieRenewalThresholdPercentage;
- tlsnegoTokenProvider.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(initiatorRequirement, this);
- tlsnegoTokenProvider.TargetAddress = initiatorRequirement.TargetAddress;
- tlsnegoTokenProvider.Via = initiatorRequirement.GetPropertyOrDefault<Uri>(InitiatorServiceModelSecurityTokenRequirement.ViaProperty, null);
- return tlsnegoTokenProvider;
- }
- SecurityTokenProvider CreateSecureConversationSecurityTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
- {
- EndpointAddress targetAddress = initiatorRequirement.TargetAddress;
- if (targetAddress == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenRequirementDoesNotSpecifyTargetAddress, initiatorRequirement));
- }
- SecurityBindingElement securityBindingElement = initiatorRequirement.SecurityBindingElement;
- if (securityBindingElement == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenProviderRequiresSecurityBindingElement, initiatorRequirement));
- }
- LocalClientSecuritySettings localClientSettings = securityBindingElement.LocalClientSettings;
- BindingContext issuerBindingContext = initiatorRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
- ChannelParameterCollection channelParameters = initiatorRequirement.GetPropertyOrDefault<ChannelParameterCollection>(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, null);
- bool isSessionMode = initiatorRequirement.SupportSecurityContextCancellation;
- if (isSessionMode)
- {
- SecuritySessionSecurityTokenProvider sessionTokenProvider = new SecuritySessionSecurityTokenProvider(GetCredentialsHandle(initiatorRequirement));
- sessionTokenProvider.BootstrapSecurityBindingElement = SecurityUtils.GetIssuerSecurityBindingElement(initiatorRequirement);
- sessionTokenProvider.IssuedSecurityTokenParameters = initiatorRequirement.GetProperty<SecurityTokenParameters>(ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty);
- sessionTokenProvider.IssuerBindingContext = issuerBindingContext;
- sessionTokenProvider.KeyEntropyMode = securityBindingElement.KeyEntropyMode;
- sessionTokenProvider.SecurityAlgorithmSuite = initiatorRequirement.SecurityAlgorithmSuite;
- sessionTokenProvider.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(initiatorRequirement, this);
- sessionTokenProvider.TargetAddress = targetAddress;
- sessionTokenProvider.Via = initiatorRequirement.GetPropertyOrDefault<Uri>(InitiatorServiceModelSecurityTokenRequirement.ViaProperty, null);
- Uri privacyNoticeUri;
- if (initiatorRequirement.TryGetProperty<Uri>(ServiceModelSecurityTokenRequirement.PrivacyNoticeUriProperty, out privacyNoticeUri))
- {
- sessionTokenProvider.PrivacyNoticeUri = privacyNoticeUri;
- }
- int privacyNoticeVersion;
- if (initiatorRequirement.TryGetProperty<int>(ServiceModelSecurityTokenRequirement.PrivacyNoticeVersionProperty, out privacyNoticeVersion))
- {
- sessionTokenProvider.PrivacyNoticeVersion = privacyNoticeVersion;
- }
- EndpointAddress localAddress;
- if (initiatorRequirement.TryGetProperty<EndpointAddress>(ServiceModelSecurityTokenRequirement.DuplexClientLocalAddressProperty, out localAddress))
- {
- sessionTokenProvider.LocalAddress = localAddress;
- }
- sessionTokenProvider.ChannelParameters = channelParameters;
- sessionTokenProvider.WebHeaders = initiatorRequirement.WebHeaders;
- return sessionTokenProvider;
- }
- else
- {
- AcceleratedTokenProvider acceleratedTokenProvider = new AcceleratedTokenProvider(GetCredentialsHandle(initiatorRequirement));
- acceleratedTokenProvider.IssuerAddress = initiatorRequirement.IssuerAddress;
- acceleratedTokenProvider.BootstrapSecurityBindingElement = SecurityUtils.GetIssuerSecurityBindingElement(initiatorRequirement);
- acceleratedTokenProvider.CacheServiceTokens = localClientSettings.CacheCookies;
- acceleratedTokenProvider.IssuerBindingContext = issuerBindingContext;
- acceleratedTokenProvider.KeyEntropyMode = securityBindingElement.KeyEntropyMode;
- acceleratedTokenProvider.MaxServiceTokenCachingTime = localClientSettings.MaxCookieCachingTime;
- acceleratedTokenProvider.SecurityAlgorithmSuite = initiatorRequirement.SecurityAlgorithmSuite;
- acceleratedTokenProvider.ServiceTokenValidityThresholdPercentage = localClientSettings.CookieRenewalThresholdPercentage;
- acceleratedTokenProvider.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(initiatorRequirement, this);
- acceleratedTokenProvider.TargetAddress = targetAddress;
- acceleratedTokenProvider.Via = initiatorRequirement.GetPropertyOrDefault<Uri>(InitiatorServiceModelSecurityTokenRequirement.ViaProperty, null);
- Uri privacyNoticeUri;
- if (initiatorRequirement.TryGetProperty<Uri>(ServiceModelSecurityTokenRequirement.PrivacyNoticeUriProperty, out privacyNoticeUri))
- {
- acceleratedTokenProvider.PrivacyNoticeUri = privacyNoticeUri;
- }
- acceleratedTokenProvider.ChannelParameters = channelParameters;
- int privacyNoticeVersion;
- if (initiatorRequirement.TryGetProperty<int>(ServiceModelSecurityTokenRequirement.PrivacyNoticeVersionProperty, out privacyNoticeVersion))
- {
- acceleratedTokenProvider.PrivacyNoticeVersion = privacyNoticeVersion;
- }
- return acceleratedTokenProvider;
- }
- }
- SecurityTokenProvider CreateServerX509TokenProvider(EndpointAddress targetAddress)
- {
- X509Certificate2 targetServerCertificate = null;
- if (targetAddress != null)
- {
- parent.ServiceCertificate.ScopedCertificates.TryGetValue(targetAddress.Uri, out targetServerCertificate);
- }
- if (targetServerCertificate == null)
- {
- targetServerCertificate = parent.ServiceCertificate.DefaultCertificate;
- }
- if ((targetServerCertificate == null) && (targetAddress.Identity != null) && (targetAddress.Identity.GetType() == typeof(X509CertificateEndpointIdentity)))
- {
- targetServerCertificate = ((X509CertificateEndpointIdentity)targetAddress.Identity).Certificates[0];
- }
- if (targetServerCertificate != null)
- {
- return new X509SecurityTokenProvider(targetServerCertificate);
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ServiceCertificateNotProvidedOnClientCredentials, targetAddress.Uri)));
- }
- }
- X509SecurityTokenAuthenticator CreateServerX509TokenAuthenticator()
- {
- return new X509SecurityTokenAuthenticator(parent.ServiceCertificate.Authentication.GetCertificateValidator(), false);
- }
- X509SecurityTokenAuthenticator CreateServerSslX509TokenAuthenticator()
- {
- if (parent.ServiceCertificate.SslCertificateAuthentication != null)
- {
- return new X509SecurityTokenAuthenticator(parent.ServiceCertificate.SslCertificateAuthentication.GetCertificateValidator(), false);
- }
- return CreateServerX509TokenAuthenticator();
- }
- bool IsDigestAuthenticationScheme(SecurityTokenRequirement requirement)
- {
- if (requirement.Properties.ContainsKey(ServiceModelSecurityTokenRequirement.HttpAuthenticationSchemeProperty))
- {
- AuthenticationSchemes authScheme = (AuthenticationSchemes)requirement.Properties[ServiceModelSecurityTokenRequirement.HttpAuthenticationSchemeProperty];
- if (!authScheme.IsSingleton())
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("value", SR.GetString(SR.HttpRequiresSingleAuthScheme, authScheme));
- }
- return (authScheme == AuthenticationSchemes.Digest);
- }
- else
- {
- return false;
- }
- }
- internal protected bool IsIssuedSecurityTokenRequirement(SecurityTokenRequirement requirement)
- {
- if (requirement != null && requirement.Properties.ContainsKey(ServiceModelSecurityTokenRequirement.IssuerAddressProperty))
- {
- // handle all issued token requirements except for spnego, tlsnego and secure conversation
- if (requirement.TokenType == ServiceModelSecurityTokenTypes.AnonymousSslnego || requirement.TokenType == ServiceModelSecurityTokenTypes.MutualSslnego
- || requirement.TokenType == ServiceModelSecurityTokenTypes.SecureConversation || requirement.TokenType == ServiceModelSecurityTokenTypes.Spnego)
- {
- return false;
- }
- else
- {
- return true;
- }
- }
- return false;
- }
- void CopyIssuerChannelBehaviorsAndAddSecurityCredentials(IssuedSecurityTokenProvider federationTokenProvider, KeyedByTypeCollection<IEndpointBehavior> issuerChannelBehaviors, EndpointAddress issuerAddress)
- {
- if (issuerChannelBehaviors != null)
- {
- foreach (IEndpointBehavior behavior in issuerChannelBehaviors)
- {
- if (behavior is SecurityCredentialsManager)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.IssuerChannelBehaviorsCannotContainSecurityCredentialsManager, issuerAddress, typeof(SecurityCredentialsManager))));
- }
- federationTokenProvider.IssuerChannelBehaviors.Add(behavior);
- }
- }
- federationTokenProvider.IssuerChannelBehaviors.Add(parent);
- }
- SecurityKeyEntropyMode GetIssuerBindingKeyEntropyModeOrDefault(Binding issuerBinding)
- {
- BindingElementCollection bindingElements = issuerBinding.CreateBindingElements();
- SecurityBindingElement securityBindingElement = bindingElements.Find<SecurityBindingElement>();
- if (securityBindingElement != null)
- {
- return securityBindingElement.KeyEntropyMode;
- }
- else
- {
- return parent.IssuedToken.DefaultKeyEntropyMode;
- }
- }
- void GetIssuerBindingSecurityVersion(Binding issuerBinding, MessageSecurityVersion issuedTokenParametersDefaultMessageSecurityVersion, SecurityBindingElement outerSecurityBindingElement, out MessageSecurityVersion messageSecurityVersion, out SecurityTokenSerializer tokenSerializer)
- {
- // Logic for setting version is:
- // 1. use issuer SBE
- // 2. use ITSP
- // 3. use outer SBE
- //
- messageSecurityVersion = null;
- if (issuerBinding != null)
- {
- BindingElementCollection bindingElements = issuerBinding.CreateBindingElements();
- SecurityBindingElement securityBindingElement = bindingElements.Find<SecurityBindingElement>();
- if (securityBindingElement != null)
- {
- messageSecurityVersion = securityBindingElement.MessageSecurityVersion;
- }
- }
- if (messageSecurityVersion == null)
- {
- if (issuedTokenParametersDefaultMessageSecurityVersion != null)
- {
- messageSecurityVersion = issuedTokenParametersDefaultMessageSecurityVersion;
- }
- else if (outerSecurityBindingElement != null)
- {
- messageSecurityVersion = outerSecurityBindingElement.MessageSecurityVersion;
- }
- }
- if (messageSecurityVersion == null)
- {
- messageSecurityVersion = MessageSecurityVersion.Default;
- }
- tokenSerializer = this.CreateSecurityTokenSerializer(messageSecurityVersion.SecurityTokenVersion);
- }
- IssuedSecurityTokenProvider CreateIssuedSecurityTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement, FederatedClientCredentialsParameters actAsOnBehalfOfParameters)
- {
- if (initiatorRequirement.TargetAddress == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenRequirementDoesNotSpecifyTargetAddress, initiatorRequirement));
- }
- SecurityBindingElement securityBindingElement = initiatorRequirement.SecurityBindingElement;
- if (securityBindingElement == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenProviderRequiresSecurityBindingElement, initiatorRequirement));
- }
- EndpointAddress issuerAddress = initiatorRequirement.IssuerAddress;
- Binding issuerBinding = initiatorRequirement.IssuerBinding;
- //
- // If the issuer address is indeed anonymous or null, we will try the local issuer
- //
- bool isLocalIssuer = (issuerAddress == null || issuerAddress.Equals(EndpointAddress.AnonymousAddress));
- if (isLocalIssuer)
- {
- issuerAddress = parent.IssuedToken.LocalIssuerAddress;
- issuerBinding = parent.IssuedToken.LocalIssuerBinding;
- }
- if (issuerAddress == null)
- {
- // if issuer address is still null then the user forgot to specify the local issuer
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.StsAddressNotSet, initiatorRequirement.TargetAddress)));
- }
- if (issuerBinding == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.StsBindingNotSet, issuerAddress)));
- }
- Uri issuerUri = issuerAddress.Uri;
- KeyedByTypeCollection<IEndpointBehavior> issuerChannelBehaviors;
- if (!parent.IssuedToken.IssuerChannelBehaviors.TryGetValue(issuerAddress.Uri, out issuerChannelBehaviors) && isLocalIssuer)
- {
- issuerChannelBehaviors = parent.IssuedToken.LocalIssuerChannelBehaviors;
- }
- IssuedSecurityTokenProvider federationTokenProvider = new IssuedSecurityTokenProvider(GetCredentialsHandle(initiatorRequirement));
- federationTokenProvider.TokenHandlerCollectionManager = this.parent.SecurityTokenHandlerCollectionManager;
- federationTokenProvider.TargetAddress = initiatorRequirement.TargetAddress;
- CopyIssuerChannelBehaviorsAndAddSecurityCredentials(federationTokenProvider, issuerChannelBehaviors, issuerAddress);
- federationTokenProvider.CacheIssuedTokens = parent.IssuedToken.CacheIssuedTokens;
- federationTokenProvider.IdentityVerifier = securityBindingElement.LocalClientSettings.IdentityVerifier;
- federationTokenProvider.IssuerAddress = issuerAddress;
- federationTokenProvider.IssuerBinding = issuerBinding;
- federationTokenProvider.KeyEntropyMode = GetIssuerBindingKeyEntropyModeOrDefault(issuerBinding);
- federationTokenProvider.MaxIssuedTokenCachingTime = parent.IssuedToken.MaxIssuedTokenCachingTime;
- federationTokenProvider.SecurityAlgorithmSuite = initiatorRequirement.SecurityAlgorithmSuite;
- MessageSecurityVersion issuerSecurityVersion;
- SecurityTokenSerializer issuerSecurityTokenSerializer;
- IssuedSecurityTokenParameters issuedTokenParameters = initiatorRequirement.GetProperty<IssuedSecurityTokenParameters>(ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty);
- GetIssuerBindingSecurityVersion(issuerBinding, issuedTokenParameters.DefaultMessageSecurityVersion, initiatorRequirement.SecurityBindingElement, out issuerSecurityVersion, out issuerSecurityTokenSerializer);
- federationTokenProvider.MessageSecurityVersion = issuerSecurityVersion;
- federationTokenProvider.SecurityTokenSerializer = issuerSecurityTokenSerializer;
- federationTokenProvider.IssuedTokenRenewalThresholdPercentage = parent.IssuedToken.IssuedTokenRenewalThresholdPercentage;
- IEnumerable<XmlElement> tokenRequestParameters = issuedTokenParameters.CreateRequestParameters(issuerSecurityVersion, issuerSecurityTokenSerializer);
- if (tokenRequestParameters != null)
- {
- foreach (XmlElement requestParameter in tokenRequestParameters)
- {
- federationTokenProvider.TokenRequestParameters.Add(requestParameter);
- }
- }
- ChannelParameterCollection channelParameters;
- if (initiatorRequirement.TryGetProperty<ChannelParameterCollection>(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, out channelParameters))
- {
- federationTokenProvider.ChannelParameters = channelParameters;
- }
- federationTokenProvider.SetupActAsOnBehalfOfParameters(actAsOnBehalfOfParameters);
- return federationTokenProvider;
- }
- public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
- {
- return this.CreateSecurityTokenProvider(tokenRequirement, false);
- }
- internal SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement, bool disableInfoCard)
- {
- if (tokenRequirement == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenRequirement");
- }
- SecurityTokenProvider result = null;
- if (disableInfoCard || !CardSpaceTryCreateSecurityTokenProviderStub(tokenRequirement, this, out result))
- {
- if (tokenRequirement is RecipientServiceModelSecurityTokenRequirement && tokenRequirement.TokenType == SecurityTokenTypes.X509Certificate && tokenRequirement.KeyUsage == SecurityKeyUsage.Exchange)
- {
- // this is the uncorrelated duplex case
- if (parent.ClientCertificate.Certificate == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ClientCertificateNotProvidedOnClientCredentials)));
- }
- result = new X509SecurityTokenProvider(parent.ClientCertificate.Certificate);
- }
- else if (tokenRequirement is InitiatorServiceModelSecurityTokenRequirement)
- {
- InitiatorServiceModelSecurityTokenRequirement initiatorRequirement = tokenRequirement as InitiatorServiceModelSecurityTokenRequirement;
- #pragma warning suppress 56506 // initiatorRequirement will never be null due to the preceding 'is' validation.
- string tokenType = initiatorRequirement.TokenType;
- if (IsIssuedSecurityTokenRequirement(initiatorRequirement))
- {
- FederatedClientCredentialsParameters additionalParameters = this.FindFederatedChannelParameters(tokenRequirement);
- if (additionalParameters != null && additionalParameters.IssuedSecurityToken != null)
- {
- return new SimpleSecurityTokenProvider(additionalParameters.IssuedSecurityToken, tokenRequirement);
- }
-
- result = CreateIssuedSecurityTokenProvider(initiatorRequirement, additionalParameters);
- }
- else if (tokenType == SecurityTokenTypes.X509Certificate)
- {
- if (initiatorRequirement.Properties.ContainsKey(SecurityTokenRequirement.KeyUsageProperty) && initiatorRequirement.KeyUsage == SecurityKeyUsage.Exchange)
- {
- result = CreateServerX509TokenProvider(initiatorRequirement.TargetAddress);
- }
- else
- {
- if (parent.ClientCertificate.Certificate == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ClientCertificateNotProvidedOnClientCredentials)));
- }
- result = new X509SecurityTokenProvider(parent.ClientCertificate.Certificate);
- }
- }
- else if (tokenType == SecurityTokenTypes.Kerberos)
- {
- string spn = GetServicePrincipalName(initiatorRequirement);
- result = new KerberosSecurityTokenProviderWrapper(
- new KerberosSecurityTokenProvider(spn, parent.Windows.AllowedImpersonationLevel, SecurityUtils.GetNetworkCredentialOrDefault(parent.Windows.ClientCredential)),
- GetCredentialsHandle(initiatorRequirement));
- }
- else if (tokenType == SecurityTokenTypes.UserName)
- {
- if (parent.UserName.UserName == null )
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UserNamePasswordNotProvidedOnClientCredentials)));
- }
- result = new UserNameSecurityTokenProvider(parent.UserName.UserName, parent.UserName.Password);
- }
- else if (tokenType == ServiceModelSecurityTokenTypes.SspiCredential)
- {
- if (IsDigestAuthenticationScheme(initiatorRequirement))
- {
- result = new SspiSecurityTokenProvider(SecurityUtils.GetNetworkCredentialOrDefault(parent.HttpDigest.ClientCredential), true, parent.HttpDigest.AllowedImpersonationLevel);
- }
- else
- {
- #pragma warning disable 618 // to disable AllowNtlm obsolete wanring.
-
- result = new SspiSecurityTokenProvider(SecurityUtils.GetNetworkCredentialOrDefault(parent.Windows.ClientCredential),
-
- parent.Windows.AllowNtlm,
- parent.Windows.AllowedImpersonationLevel);
- #pragma warning restore 618
-
- }
- }
- else if (tokenType == ServiceModelSecurityTokenTypes.Spnego)
- {
- result = CreateSpnegoTokenProvider(initiatorRequirement);
- }
- else if (tokenType == ServiceModelSecurityTokenTypes.MutualSslnego)
- {
- result = CreateTlsnegoTokenProvider(initiatorRequirement, true);
- }
- else if (tokenType == ServiceModelSecurityTokenTypes.AnonymousSslnego)
- {
- result = CreateTlsnegoTokenProvider(initiatorRequirement, false);
- }
- else if (tokenType == ServiceModelSecurityTokenTypes.SecureConversation)
- {
- result = CreateSecureConversationSecurityTokenProvider(initiatorRequirement);
- }
- }
- }
- if ((result == null) && !tokenRequirement.IsOptionalToken)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateProviderForRequirement, tokenRequirement)));
- }
- return result;
- }
- bool CardSpaceTryCreateSecurityTokenProviderStub(SecurityTokenRequirement tokenRequirement, ClientCredentialsSecurityTokenManager clientCredentialsTokenManager, out SecurityTokenProvider provider)
- {
- return InfoCardHelper.TryCreateSecurityTokenProvider(tokenRequirement, clientCredentialsTokenManager, out provider);
- }
- protected SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityVersion version)
- {
- if (version == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("version"));
- }
- return this.CreateSecurityTokenSerializer(MessageSecurityTokenVersion.GetSecurityTokenVersion(version, true));
- }
- public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
- {
- if (version == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version");
- }
- if (this.parent != null && this.parent.UseIdentityConfiguration)
- {
- return this.WrapTokenHandlersAsSecurityTokenSerializer(version);
- }
- MessageSecurityTokenVersion wsVersion = version as MessageSecurityTokenVersion;
- if (wsVersion != null)
- {
- return new WSSecurityTokenSerializer(wsVersion.SecurityVersion, wsVersion.TrustVersion, wsVersion.SecureConversationVersion, wsVersion.EmitBspRequiredAttributes, null, null, null);
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateSerializerForVersion, version)));
- }
- }
- private SecurityTokenSerializer WrapTokenHandlersAsSecurityTokenSerializer(SecurityTokenVersion version)
- {
- TrustVersion trustVersion = TrustVersion.WSTrust13;
- SecureConversationVersion scVersion = SecureConversationVersion.WSSecureConversation13;
- SecurityVersion securityVersion = SecurityVersion.WSSecurity11;
- foreach (string securitySpecification in version.GetSecuritySpecifications())
- {
- if (StringComparer.Ordinal.Equals(securitySpecification, WSTrustFeb2005Constants.NamespaceURI))
- {
- trustVersion = TrustVersion.WSTrustFeb2005;
- }
- else if (StringComparer.Ordinal.Equals(securitySpecification, WSTrust13Constants.NamespaceURI))
- {
- trustVersion = TrustVersion.WSTrust13;
- }
- else if (StringComparer.Ordinal.Equals(securitySpecification, System.IdentityModel.WSSecureConversationFeb2005Constants.Namespace))
- {
- scVersion = SecureConversationVersion.WSSecureConversationFeb2005;
- }
- else if (StringComparer.Ordinal.Equals(securitySpecification, System.IdentityModel.WSSecureConversation13Constants.Namespace))
- {
- scVersion = SecureConversationVersion.WSSecureConversation13;
- }
- }
- securityVersion = FederatedSecurityTokenManager.GetSecurityVersion(version);
- //
- //
- SecurityTokenHandlerCollectionManager sthcm = this.parent.SecurityTokenHandlerCollectionManager;
- WsSecurityTokenSerializerAdapter adapter = new WsSecurityTokenSerializerAdapter(sthcm[SecurityTokenHandlerCollectionManager.Usage.Default], securityVersion, trustVersion, scVersion, false, null, null, null);
- return adapter;
- }
- public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
- {
- if (tokenRequirement == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenRequirement");
- }
- outOfBandTokenResolver = null;
- SecurityTokenAuthenticator result = null;
- InitiatorServiceModelSecurityTokenRequirement initiatorRequirement = tokenRequirement as InitiatorServiceModelSecurityTokenRequirement;
- if (initiatorRequirement != null)
- {
- string tokenType = initiatorRequirement.TokenType;
- if (IsIssuedSecurityTokenRequirement(initiatorRequirement))
- {
- return new GenericXmlSecurityTokenAuthenticator();
- }
- else if (tokenType == SecurityTokenTypes.X509Certificate)
- {
- if (initiatorRequirement.IsOutOfBandToken)
- {
- // when the client side soap security asks for a token authenticator, its for doing
- // identity checks on the out of band server certificate
- result = new X509SecurityTokenAuthenticator(X509CertificateValidator.None);
- }
- else if (initiatorRequirement.PreferSslCertificateAuthenticator)
- {
- result = CreateServerSslX509TokenAuthenticator();
- }
- else
- {
- result = CreateServerX509TokenAuthenticator();
- }
- }
- else if (tokenType == SecurityTokenTypes.Rsa)
- {
- result = new RsaSecurityTokenAuthenticator();
- }
- else if (tokenType == SecurityTokenTypes.Kerberos)
- {
- result = new KerberosRequestorSecurityTokenAuthenticator();
- }
- else if (tokenType == ServiceModelSecurityTokenTypes.SecureConversation
- || tokenType == ServiceModelSecurityTokenTypes.MutualSslnego
- || tokenType == ServiceModelSecurityTokenTypes.AnonymousSslnego
- || tokenType == ServiceModelSecurityTokenTypes.Spnego)
- {
- result = new GenericXmlSecurityTokenAuthenticator();
- }
- }
- else if ((tokenRequirement is RecipientServiceModelSecurityTokenRequirement) && tokenRequirement.TokenType == SecurityTokenTypes.X509Certificate)
- {
- // uncorrelated duplex case
- result = CreateServerX509TokenAuthenticator();
- }
- if (result == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateAuthenticatorForRequirement, tokenRequirement)));
- }
- return result;
- }
- SafeFreeCredentials GetCredentialsHandle(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
- {
- SspiIssuanceChannelParameter sspiChannelParameter = GetSspiIssuanceChannelParameter(initiatorRequirement);
- return sspiChannelParameter != null ? sspiChannelParameter.CredentialsHandle : null;
- }
- /// <summary>
- /// Looks for the first FederatedClientCredentialsParameters object in the ChannelParameterCollection
- /// property on the tokenRequirement.
- /// </summary>
- internal FederatedClientCredentialsParameters FindFederatedChannelParameters(SecurityTokenRequirement tokenRequirement)
- {
- FederatedClientCredentialsParameters issuedTokenClientCredentialsParameters = null;
- ChannelParameterCollection channelParameterCollection = null;
- if (tokenRequirement.TryGetProperty<ChannelParameterCollection>(
- ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty,
- out channelParameterCollection))
- {
- if (channelParameterCollection != null)
- {
- foreach (object obj in channelParameterCollection)
- {
- issuedTokenClientCredentialsParameters = obj as FederatedClientCredentialsParameters;
- if (issuedTokenClientCredentialsParameters != null)
- {
- break;
- }
- }
- }
- }
- return issuedTokenClientCredentialsParameters;
- }
- internal class KerberosSecurityTokenProviderWrapper : CommunicationObjectSecurityTokenProvider
- {
- KerberosSecurityTokenProvider innerProvider;
- SafeFreeCredentials credentialsHandle;
- bool ownCredentialsHandle = false;
-
- public KerberosSecurityTokenProviderWrapper(KerberosSecurityTokenProvider innerProvider, SafeFreeCredentials credentialsHandle)
- {
- this.innerProvider = innerProvider;
- this.credentialsHandle = credentialsHandle;
- }
- public override void OnOpening()
- {
- base.OnOpening();
- if (this.credentialsHandle == null)
- {
- this.credentialsHandle = SecurityUtils.GetCredentialsHandle("Kerberos", this.innerProvider.NetworkCredential, false);
- this.ownCredentialsHandle = true;
- }
- }
- public override void OnClose(TimeSpan timeout)
- {
- base.OnClose(timeout);
- FreeCredentialsHandle();
- }
- public override void OnAbort()
- {
- base.OnAbort();
- FreeCredentialsHandle();
- }
- void FreeCredentialsHandle()
- {
- if (this.credentialsHandle != null)
- {
- if (this.ownCredentialsHandle)
- {
- this.credentialsHandle.Close();
- }
- this.credentialsHandle = null;
- }
- }
- internal SecurityToken GetToken(TimeSpan timeout, ChannelBinding channelbinding)
- {
- return new KerberosRequestorSecurityToken(this.innerProvider.ServicePrincipalName,
- this.innerProvider.TokenImpersonationLevel, this.innerProvider.NetworkCredential,
- SecurityUniqueId.Create().Value, this.credentialsHandle, channelbinding);
- }
- protected override SecurityToken GetTokenCore(TimeSpan timeout)
- {
- return this.GetToken(timeout, null);
- }
- }
- }
- }
|