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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DownloadProgressEventArgs.cs
- ChannelProtectionRequirements.cs
- SoapSchemaMember.cs
- ParserStreamGeometryContext.cs
- InertiaRotationBehavior.cs
- CustomAssemblyResolver.cs
- MemberCollection.cs
- UniformGrid.cs
- _SafeNetHandles.cs
- ICollection.cs
- IdentityReference.cs
- Transform3DGroup.cs
- FullTextLine.cs
- DataServiceResponse.cs
- PermissionSetTriple.cs
- DayRenderEvent.cs
- ResponseBodyWriter.cs
- NotImplementedException.cs
- StylusSystemGestureEventArgs.cs
- XMLSyntaxException.cs
- TableRowCollection.cs
- DataContractSerializerOperationBehavior.cs
- PersonalizationStateInfoCollection.cs
- glyphs.cs
- _ContextAwareResult.cs
- XmlDataSourceDesigner.cs
- DelegateBodyWriter.cs
- ObjectPropertyMapping.cs
- ModuleBuilder.cs
- Currency.cs
- Page.cs
- CompositeControl.cs
- GridToolTip.cs
- WorkflowDefinitionContext.cs
- Pens.cs
- XPathMessageFilterElementCollection.cs
- WebPartCollection.cs
- OracleConnectionStringBuilder.cs
- InputScopeManager.cs
- TextTreeDeleteContentUndoUnit.cs
- DoubleLinkListEnumerator.cs
- ColorAnimationUsingKeyFrames.cs
- MD5CryptoServiceProvider.cs
- SRDisplayNameAttribute.cs
- UnmanagedMemoryStream.cs
- HotSpot.cs
- SecurityTokenRequirement.cs
- TriState.cs
- CapiSymmetricAlgorithm.cs
- FileSystemWatcher.cs
- TextEditorContextMenu.cs
- SafeHandle.cs
- NativeMethods.cs
- ParentControlDesigner.cs
- LayoutEngine.cs
- MenuItemStyle.cs
- InheritanceAttribute.cs
- Normalization.cs
- TransactionalPackage.cs
- DiscardableAttribute.cs
- ConnectionPoint.cs
- Version.cs
- HierarchicalDataTemplate.cs
- ObjectQueryState.cs
- TreeNodeClickEventArgs.cs
- ReversePositionQuery.cs
- XmlNotation.cs
- SmtpSpecifiedPickupDirectoryElement.cs
- FloatAverageAggregationOperator.cs
- ChtmlTextWriter.cs
- HashCodeCombiner.cs
- TemplateBamlTreeBuilder.cs
- ScrollChrome.cs
- XmlSchemaException.cs
- TreeViewEvent.cs
- WorkflowDesigner.cs
- MultiView.cs
- DataBoundControlAdapter.cs
- UrlPath.cs
- ListViewSelectEventArgs.cs
- ResourceExpressionEditorSheet.cs
- DllNotFoundException.cs
- TextContainer.cs
- OleDbCommand.cs
- XmlBufferReader.cs
- NavigationWindow.cs
- WsatAdminException.cs
- OrderedDictionary.cs
- AppSettingsReader.cs
- Facet.cs
- OrderedDictionaryStateHelper.cs
- ChoiceConverter.cs
- IsolationInterop.cs
- DiscreteKeyFrames.cs
- ViewUtilities.cs
- metadatamappinghashervisitor.hashsourcebuilder.cs
- XmlSerializerAssemblyAttribute.cs
- ListItemsPage.cs
- DecimalKeyFrameCollection.cs
- TemplateDefinition.cs