ClientCredentialsSecurityTokenManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Security / ClientCredentialsSecurityTokenManager.cs / 1 / ClientCredentialsSecurityTokenManager.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.ServiceModel 
{
    using System.Collections.Generic; 
    using System.ServiceModel.Channels; 
    using System.ServiceModel.Description;
    using System.IdentityModel.Tokens; 
    using System.IdentityModel.Selectors;
    using System.Runtime.Serialization;
    using System.ServiceModel.Security;
 
    using System.Net;
    using System.Collections.ObjectModel; 
    using System.Security.Principal; 
    using System.Xml;
    using System.ServiceModel.Security.Tokens; 
    using System.Security.Cryptography.X509Certificates;

    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(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 && sspiChannelParameter.GetTokenOnOpen; 
            LocalClientSecuritySettings localClientSettings = securityBindingElement.LocalClientSettings;
            BindingContext issuerBindingContext = initiatorRequirement.GetProperty(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty); 
            SpnegoTokenProvider spnegoTokenProvider = new SpnegoTokenProvider(sspiChannelParameter != null ? sspiChannelParameter.CredentialsHandle : null);
            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(InitiatorServiceModelSecurityTokenRequirement.ViaProperty, null); 
            spnegoTokenProvider.ApplicationProtectionRequirements = (issuerBindingContext != null) ? issuerBindingContext.BindingParameters.Find() : null;

            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(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(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(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(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() : 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(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(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
            ChannelParameterCollection channelParameters = initiatorRequirement.GetPropertyOrDefault(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, null); 
            bool isSessionMode = initiatorRequirement.SupportSecurityContextCancellation; 
            if (isSessionMode)
            { 
                SecuritySessionSecurityTokenProvider sessionTokenProvider = new SecuritySessionSecurityTokenProvider(GetCredentialsHandle(initiatorRequirement));
                sessionTokenProvider.BootstrapSecurityBindingElement = SecurityUtils.GetIssuerSecurityBindingElement(initiatorRequirement);
                sessionTokenProvider.IssuedSecurityTokenParameters = initiatorRequirement.GetProperty(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(InitiatorServiceModelSecurityTokenRequirement.ViaProperty, null); 
                Uri privacyNoticeUri;
                if (initiatorRequirement.TryGetProperty(ServiceModelSecurityTokenRequirement.PrivacyNoticeUriProperty, out privacyNoticeUri))
                {
                    sessionTokenProvider.PrivacyNoticeUri = privacyNoticeUri; 
                }
                int privacyNoticeVersion; 
                if (initiatorRequirement.TryGetProperty(ServiceModelSecurityTokenRequirement.PrivacyNoticeVersionProperty, out privacyNoticeVersion)) 
                {
                    sessionTokenProvider.PrivacyNoticeVersion = privacyNoticeVersion; 
                }
                EndpointAddress localAddress;
                if (initiatorRequirement.TryGetProperty(ServiceModelSecurityTokenRequirement.DuplexClientLocalAddressProperty, out localAddress))
                { 
                    sessionTokenProvider.LocalAddress = localAddress;
                } 
                sessionTokenProvider.ChannelParameters = channelParameters; 
                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(InitiatorServiceModelSecurityTokenRequirement.ViaProperty, null);
                Uri privacyNoticeUri; 
                if (initiatorRequirement.TryGetProperty(ServiceModelSecurityTokenRequirement.PrivacyNoticeUriProperty, out privacyNoticeUri)) 
                {
                    acceleratedTokenProvider.PrivacyNoticeUri = privacyNoticeUri; 
                }
                acceleratedTokenProvider.ChannelParameters = channelParameters;
                int privacyNoticeVersion;
                if (initiatorRequirement.TryGetProperty(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);
        } 

        bool IsDigestAuthenticationScheme(SecurityTokenRequirement requirement) 
        { 
            if (requirement.Properties.ContainsKey(ServiceModelSecurityTokenRequirement.HttpAuthenticationSchemeProperty))
            { 
                AuthenticationSchemes authScheme = (AuthenticationSchemes)requirement.Properties[ServiceModelSecurityTokenRequirement.HttpAuthenticationSchemeProperty];
                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 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();
            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();
                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)
        { 
            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 issuerChannelBehaviors; 
            if (!parent.IssuedToken.IssuerChannelBehaviors.TryGetValue(issuerAddress.Uri, out issuerChannelBehaviors) && isLocalIssuer)
            {
                issuerChannelBehaviors = parent.IssuedToken.LocalIssuerChannelBehaviors;
            } 

            IssuedSecurityTokenProvider federationTokenProvider = new IssuedSecurityTokenProvider(GetCredentialsHandle(initiatorRequirement)); 
            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(ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty); 

            GetIssuerBindingSecurityVersion(issuerBinding, issuedTokenParameters.DefaultMessageSecurityVersion, initiatorRequirement.SecurityBindingElement, out issuerSecurityVersion, out issuerSecurityTokenSerializer);
            federationTokenProvider.MessageSecurityVersion = issuerSecurityVersion;
            federationTokenProvider.SecurityTokenSerializer = issuerSecurityTokenSerializer; 
            federationTokenProvider.IssuedTokenRenewalThresholdPercentage = parent.IssuedToken.IssuedTokenRenewalThresholdPercentage;
 
            IEnumerable tokenRequestParameters = issuedTokenParameters.CreateRequestParameters(issuerSecurityVersion, issuerSecurityTokenSerializer); 
            if (tokenRequestParameters != null)
            { 
                foreach (XmlElement requestParameter in tokenRequestParameters)
                {
                    federationTokenProvider.TokenRequestParameters.Add(requestParameter);
                } 
            }
            ChannelParameterCollection channelParameters; 
            if (initiatorRequirement.TryGetProperty(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, out channelParameters)) 
            {
                federationTokenProvider.ChannelParameters = channelParameters; 
            }
            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 || !InfoCardHelper.TryCreateSecurityTokenProvider(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)) 
                    {
                        result = CreateIssuedSecurityTokenProvider(initiatorRequirement); 
                    }
                    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
                        {
                            result = new SspiSecurityTokenProvider(SecurityUtils.GetNetworkCredentialOrDefault(parent.Windows.ClientCredential), parent.Windows.AllowNtlm, parent.Windows.AllowedImpersonationLevel); 
                        }
                    } 
                    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)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateProviderForRequirement, tokenRequirement)));
            }

            return result; 
        }
 
        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");
            }
            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)));
            }
        } 

        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
                    { 
                        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; 
        }
 
        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; 
                }
            } 

            protected override SecurityToken GetTokenCore(TimeSpan timeout)
            {
                return new KerberosRequestorSecurityToken(this.innerProvider.ServicePrincipalName, this.innerProvider.TokenImpersonationLevel, 
                    this.innerProvider.NetworkCredential, SecurityUniqueId.Create().Value, this.credentialsHandle);
            } 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK