| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593 |
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace System.ServiceModel.Security
- {
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.IdentityModel.Policy;
- using System.IdentityModel.Selectors;
- using System.IdentityModel.Tokens;
- using System.Net;
- using System.Security.Authentication.ExtendedProtection;
- using System.ServiceModel;
- using System.ServiceModel.Channels;
- using System.ServiceModel.Description;
- using System.ServiceModel.Dispatcher;
- using System.ServiceModel.Security.Tokens;
- public class ServiceCredentialsSecurityTokenManager : SecurityTokenManager, IEndpointIdentityProvider
- {
- ServiceCredentials parent;
- public ServiceCredentialsSecurityTokenManager(ServiceCredentials parent)
- {
- if (parent == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parent");
- }
- this.parent = parent;
- }
- public ServiceCredentials ServiceCredentials
- {
- get { return parent; }
- }
- public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
- {
- if (version == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version");
- }
- MessageSecurityTokenVersion wsVersion = version as MessageSecurityTokenVersion;
- if (wsVersion != null)
- {
- SamlSerializer samlSerializer = null;
- if (parent.IssuedTokenAuthentication != null)
- samlSerializer = parent.IssuedTokenAuthentication.SamlSerializer;
- else
- samlSerializer = new SamlSerializer();
- return new WSSecurityTokenSerializer(wsVersion.SecurityVersion, wsVersion.TrustVersion, wsVersion.SecureConversationVersion, wsVersion.EmitBspRequiredAttributes, samlSerializer, parent.SecureConversationAuthentication.SecurityStateEncoder, parent.SecureConversationAuthentication.SecurityContextClaimTypes);
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateSerializerForVersion, version)));
- }
- }
- protected SecurityTokenAuthenticator CreateSecureConversationTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, bool preserveBootstrapTokens, out SecurityTokenResolver sctResolver)
- {
- SecurityBindingElement securityBindingElement = recipientRequirement.SecurityBindingElement;
- if (securityBindingElement == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenAuthenticatorRequiresSecurityBindingElement, recipientRequirement));
- }
- bool isCookieMode = !recipientRequirement.SupportSecurityContextCancellation;
- LocalServiceSecuritySettings localServiceSettings = securityBindingElement.LocalServiceSettings;
- IMessageFilterTable<EndpointAddress> endpointFilterTable = recipientRequirement.GetPropertyOrDefault<IMessageFilterTable<EndpointAddress>>(ServiceModelSecurityTokenRequirement.EndpointFilterTableProperty, null);
- if (!isCookieMode)
- {
- sctResolver = new SecurityContextSecurityTokenResolver(Int32.MaxValue, false);
- // remember this authenticator for future reference
- SecuritySessionSecurityTokenAuthenticator authenticator = new SecuritySessionSecurityTokenAuthenticator();
- authenticator.BootstrapSecurityBindingElement = SecurityUtils.GetIssuerSecurityBindingElement(recipientRequirement);
- authenticator.IssuedSecurityTokenParameters = recipientRequirement.GetProperty<SecurityTokenParameters>(ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty);
- authenticator.IssuedTokenCache = (ISecurityContextSecurityTokenCache)sctResolver;
- authenticator.IssuerBindingContext = recipientRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
- authenticator.KeyEntropyMode = securityBindingElement.KeyEntropyMode;
- authenticator.ListenUri = recipientRequirement.ListenUri;
- authenticator.SecurityAlgorithmSuite = recipientRequirement.SecurityAlgorithmSuite;
- authenticator.SessionTokenLifetime = TimeSpan.MaxValue;
- authenticator.KeyRenewalInterval = securityBindingElement.LocalServiceSettings.SessionKeyRenewalInterval;
- authenticator.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(recipientRequirement, this);
- authenticator.EndpointFilterTable = endpointFilterTable;
- authenticator.MaximumConcurrentNegotiations = localServiceSettings.MaxStatefulNegotiations;
- authenticator.NegotiationTimeout = localServiceSettings.NegotiationTimeout;
- authenticator.PreserveBootstrapTokens = preserveBootstrapTokens;
- return authenticator;
- }
- else
- {
- sctResolver = new SecurityContextSecurityTokenResolver(localServiceSettings.MaxCachedCookies, true, localServiceSettings.MaxClockSkew);
- AcceleratedTokenAuthenticator authenticator = new AcceleratedTokenAuthenticator();
- authenticator.BootstrapSecurityBindingElement = SecurityUtils.GetIssuerSecurityBindingElement(recipientRequirement);
- authenticator.KeyEntropyMode = securityBindingElement.KeyEntropyMode;
- authenticator.EncryptStateInServiceToken = true;
- authenticator.IssuedSecurityTokenParameters = recipientRequirement.GetProperty<SecurityTokenParameters>(ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty);
- authenticator.IssuedTokenCache = (ISecurityContextSecurityTokenCache)sctResolver;
- authenticator.IssuerBindingContext = recipientRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
- authenticator.ListenUri = recipientRequirement.ListenUri;
- authenticator.SecurityAlgorithmSuite = recipientRequirement.SecurityAlgorithmSuite;
- authenticator.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(recipientRequirement, this);
- authenticator.SecurityStateEncoder = parent.SecureConversationAuthentication.SecurityStateEncoder;
- authenticator.KnownTypes = parent.SecureConversationAuthentication.SecurityContextClaimTypes;
- authenticator.PreserveBootstrapTokens = preserveBootstrapTokens;
- // local security quotas
- authenticator.MaximumCachedNegotiationState = localServiceSettings.MaxStatefulNegotiations;
- authenticator.NegotiationTimeout = localServiceSettings.NegotiationTimeout;
- authenticator.ServiceTokenLifetime = localServiceSettings.IssuedCookieLifetime;
- authenticator.MaximumConcurrentNegotiations = localServiceSettings.MaxStatefulNegotiations;
- // audit settings
- authenticator.AuditLogLocation = recipientRequirement.AuditLogLocation;
- authenticator.SuppressAuditFailure = recipientRequirement.SuppressAuditFailure;
- authenticator.MessageAuthenticationAuditLevel = recipientRequirement.MessageAuthenticationAuditLevel;
- authenticator.EndpointFilterTable = endpointFilterTable;
- return authenticator;
- }
- }
- SecurityTokenAuthenticator CreateSpnegoSecurityTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, out SecurityTokenResolver sctResolver)
- {
- SecurityBindingElement securityBindingElement = recipientRequirement.SecurityBindingElement;
- if (securityBindingElement == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenAuthenticatorRequiresSecurityBindingElement, recipientRequirement));
- }
- bool isCookieMode = !recipientRequirement.SupportSecurityContextCancellation;
- LocalServiceSecuritySettings localServiceSettings = securityBindingElement.LocalServiceSettings;
- sctResolver = new SecurityContextSecurityTokenResolver(localServiceSettings.MaxCachedCookies, true);
- ExtendedProtectionPolicy extendedProtectionPolicy = null;
- recipientRequirement.TryGetProperty<ExtendedProtectionPolicy>(ServiceModelSecurityTokenRequirement.ExtendedProtectionPolicy, out extendedProtectionPolicy);
- SpnegoTokenAuthenticator authenticator = new SpnegoTokenAuthenticator();
- authenticator.ExtendedProtectionPolicy = extendedProtectionPolicy;
- authenticator.AllowUnauthenticatedCallers = parent.WindowsAuthentication.AllowAnonymousLogons;
- authenticator.ExtractGroupsForWindowsAccounts = parent.WindowsAuthentication.IncludeWindowsGroups;
- authenticator.IsClientAnonymous = false;
- authenticator.EncryptStateInServiceToken = isCookieMode;
- authenticator.IssuedSecurityTokenParameters = recipientRequirement.GetProperty<SecurityTokenParameters>(ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty);
- authenticator.IssuedTokenCache = (ISecurityContextSecurityTokenCache)sctResolver;
- authenticator.IssuerBindingContext = recipientRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
- authenticator.ListenUri = recipientRequirement.ListenUri;
- authenticator.SecurityAlgorithmSuite = recipientRequirement.SecurityAlgorithmSuite;
- authenticator.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(recipientRequirement, this);
- authenticator.SecurityStateEncoder = parent.SecureConversationAuthentication.SecurityStateEncoder;
- authenticator.KnownTypes = parent.SecureConversationAuthentication.SecurityContextClaimTypes;
- // if the SPNEGO is being done in mixed-mode, the nego blobs are from an anonymous client and so there size bound needs to be enforced.
- if (securityBindingElement is TransportSecurityBindingElement)
- {
- authenticator.MaxMessageSize = SecurityUtils.GetMaxNegotiationBufferSize(authenticator.IssuerBindingContext);
- }
- // local security quotas
- authenticator.MaximumCachedNegotiationState = localServiceSettings.MaxStatefulNegotiations;
- authenticator.NegotiationTimeout = localServiceSettings.NegotiationTimeout;
- authenticator.ServiceTokenLifetime = localServiceSettings.IssuedCookieLifetime;
- authenticator.MaximumConcurrentNegotiations = localServiceSettings.MaxStatefulNegotiations;
- // audit settings
- authenticator.AuditLogLocation = recipientRequirement.AuditLogLocation;
- authenticator.SuppressAuditFailure = recipientRequirement.SuppressAuditFailure;
- authenticator.MessageAuthenticationAuditLevel = recipientRequirement.MessageAuthenticationAuditLevel;
- return authenticator;
- }
- SecurityTokenAuthenticator CreateTlsnegoClientX509TokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement)
- {
- RecipientServiceModelSecurityTokenRequirement clientX509Requirement = new RecipientServiceModelSecurityTokenRequirement();
- clientX509Requirement.TokenType = SecurityTokenTypes.X509Certificate;
- clientX509Requirement.KeyUsage = SecurityKeyUsage.Signature;
- clientX509Requirement.ListenUri = recipientRequirement.ListenUri;
- clientX509Requirement.KeyType = SecurityKeyType.AsymmetricKey;
- clientX509Requirement.SecurityBindingElement = recipientRequirement.SecurityBindingElement;
- SecurityTokenResolver dummy;
- return this.CreateSecurityTokenAuthenticator(clientX509Requirement, out dummy);
- }
- SecurityTokenProvider CreateTlsnegoServerX509TokenProvider(RecipientServiceModelSecurityTokenRequirement recipientRequirement)
- {
- RecipientServiceModelSecurityTokenRequirement serverX509Requirement = new RecipientServiceModelSecurityTokenRequirement();
- serverX509Requirement.TokenType = SecurityTokenTypes.X509Certificate;
- serverX509Requirement.KeyUsage = SecurityKeyUsage.Exchange;
- serverX509Requirement.ListenUri = recipientRequirement.ListenUri;
- serverX509Requirement.KeyType = SecurityKeyType.AsymmetricKey;
- serverX509Requirement.SecurityBindingElement = recipientRequirement.SecurityBindingElement;
- return this.CreateSecurityTokenProvider(serverX509Requirement);
- }
- SecurityTokenAuthenticator CreateTlsnegoSecurityTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, bool requireClientCertificate, out SecurityTokenResolver sctResolver)
- {
- SecurityBindingElement securityBindingElement = recipientRequirement.SecurityBindingElement;
- if (securityBindingElement == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenAuthenticatorRequiresSecurityBindingElement, recipientRequirement));
- }
- bool isCookieMode = !recipientRequirement.SupportSecurityContextCancellation;
- LocalServiceSecuritySettings localServiceSettings = securityBindingElement.LocalServiceSettings;
- sctResolver = new SecurityContextSecurityTokenResolver(localServiceSettings.MaxCachedCookies, true);
- TlsnegoTokenAuthenticator authenticator = new TlsnegoTokenAuthenticator();
- authenticator.IsClientAnonymous = !requireClientCertificate;
- if (requireClientCertificate)
- {
- authenticator.ClientTokenAuthenticator = this.CreateTlsnegoClientX509TokenAuthenticator(recipientRequirement);
- authenticator.MapCertificateToWindowsAccount = this.ServiceCredentials.ClientCertificate.Authentication.MapClientCertificateToWindowsAccount;
- }
- authenticator.EncryptStateInServiceToken = isCookieMode;
- authenticator.IssuedSecurityTokenParameters = recipientRequirement.GetProperty<SecurityTokenParameters>(ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty);
- authenticator.IssuedTokenCache = (ISecurityContextSecurityTokenCache)sctResolver;
- authenticator.IssuerBindingContext = recipientRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
- authenticator.ListenUri = recipientRequirement.ListenUri;
- authenticator.SecurityAlgorithmSuite = recipientRequirement.SecurityAlgorithmSuite;
- authenticator.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(recipientRequirement, this);
- authenticator.SecurityStateEncoder = parent.SecureConversationAuthentication.SecurityStateEncoder;
- authenticator.KnownTypes = parent.SecureConversationAuthentication.SecurityContextClaimTypes;
- authenticator.ServerTokenProvider = CreateTlsnegoServerX509TokenProvider(recipientRequirement);
- // local security quotas
- authenticator.MaximumCachedNegotiationState = localServiceSettings.MaxStatefulNegotiations;
- authenticator.NegotiationTimeout = localServiceSettings.NegotiationTimeout;
- authenticator.ServiceTokenLifetime = localServiceSettings.IssuedCookieLifetime;
- authenticator.MaximumConcurrentNegotiations = localServiceSettings.MaxStatefulNegotiations;
- // if the TLSNEGO is being done in mixed-mode, the nego blobs are from an anonymous client and so there size bound needs to be enforced.
- if (securityBindingElement is TransportSecurityBindingElement)
- {
- authenticator.MaxMessageSize = SecurityUtils.GetMaxNegotiationBufferSize(authenticator.IssuerBindingContext);
- }
- // audit settings
- authenticator.AuditLogLocation = recipientRequirement.AuditLogLocation;
- authenticator.SuppressAuditFailure = recipientRequirement.SuppressAuditFailure;
- authenticator.MessageAuthenticationAuditLevel = recipientRequirement.MessageAuthenticationAuditLevel;
- return authenticator;
- }
- X509SecurityTokenAuthenticator CreateClientX509TokenAuthenticator()
- {
- X509ClientCertificateAuthentication authentication = parent.ClientCertificate.Authentication;
- return new X509SecurityTokenAuthenticator(authentication.GetCertificateValidator(), authentication.MapClientCertificateToWindowsAccount, authentication.IncludeWindowsGroups);
- }
- SamlSecurityTokenAuthenticator CreateSamlTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, out SecurityTokenResolver outOfBandTokenResolver)
- {
- if (recipientRequirement == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("recipientRequirement");
- Collection<SecurityToken> outOfBandTokens = new Collection<SecurityToken>();
- if (parent.ServiceCertificate.Certificate != null)
- {
- outOfBandTokens.Add(new X509SecurityToken(parent.ServiceCertificate.Certificate));
- }
- List<SecurityTokenAuthenticator> supportingAuthenticators = new List<SecurityTokenAuthenticator>();
- if ((parent.IssuedTokenAuthentication.KnownCertificates != null) && (parent.IssuedTokenAuthentication.KnownCertificates.Count > 0))
- {
- for (int i = 0; i < parent.IssuedTokenAuthentication.KnownCertificates.Count; ++i)
- {
- outOfBandTokens.Add(new X509SecurityToken(parent.IssuedTokenAuthentication.KnownCertificates[i]));
- }
- }
- X509CertificateValidator validator = parent.IssuedTokenAuthentication.GetCertificateValidator();
- supportingAuthenticators.Add(new X509SecurityTokenAuthenticator(validator));
- if (parent.IssuedTokenAuthentication.AllowUntrustedRsaIssuers)
- {
- supportingAuthenticators.Add(new RsaSecurityTokenAuthenticator());
- }
- outOfBandTokenResolver = (outOfBandTokens.Count > 0) ? SecurityTokenResolver.CreateDefaultSecurityTokenResolver(new ReadOnlyCollection<SecurityToken>(outOfBandTokens), false) : null;
- SamlSecurityTokenAuthenticator ssta;
- if ((recipientRequirement.SecurityBindingElement == null) || (recipientRequirement.SecurityBindingElement.LocalServiceSettings == null))
- {
- ssta = new SamlSecurityTokenAuthenticator(supportingAuthenticators);
- }
- else
- {
- ssta = new SamlSecurityTokenAuthenticator(supportingAuthenticators, recipientRequirement.SecurityBindingElement.LocalServiceSettings.MaxClockSkew);
- }
- // set audience uri restrictions
- ssta.AudienceUriMode = parent.IssuedTokenAuthentication.AudienceUriMode;
- IList<string> allowedAudienceUris = ssta.AllowedAudienceUris;
- if (parent.IssuedTokenAuthentication.AllowedAudienceUris != null)
- {
- for (int i = 0; i < parent.IssuedTokenAuthentication.AllowedAudienceUris.Count; i++)
- allowedAudienceUris.Add(parent.IssuedTokenAuthentication.AllowedAudienceUris[i]);
- }
- if (recipientRequirement.ListenUri != null)
- {
- allowedAudienceUris.Add(recipientRequirement.ListenUri.AbsoluteUri);
- }
- return ssta;
- }
- X509SecurityTokenProvider CreateServerX509TokenProvider()
- {
- if (parent.ServiceCertificate.Certificate == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ServiceCertificateNotProvidedOnServiceCredentials)));
- }
- SecurityUtils.EnsureCertificateCanDoKeyExchange(parent.ServiceCertificate.Certificate);
- return new ServiceX509SecurityTokenProvider(parent.ServiceCertificate.Certificate);
- }
- protected bool IsIssuedSecurityTokenRequirement(SecurityTokenRequirement requirement)
- {
- return (requirement != null && requirement.Properties.ContainsKey(ServiceModelSecurityTokenRequirement.IssuerAddressProperty));
- }
- public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
- {
- if (tokenRequirement == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenRequirement");
- }
- string tokenType = tokenRequirement.TokenType;
- outOfBandTokenResolver = null;
- SecurityTokenAuthenticator result = null;
- if (tokenRequirement is InitiatorServiceModelSecurityTokenRequirement)
- {
- // this is the uncorrelated duplex case in which the server is asking for
- // an authenticator to validate its provisioned client certificate
- if (tokenType == SecurityTokenTypes.X509Certificate && tokenRequirement.KeyUsage == SecurityKeyUsage.Exchange)
- {
- return new X509SecurityTokenAuthenticator(X509CertificateValidator.None, false);
- }
- }
- RecipientServiceModelSecurityTokenRequirement recipientRequirement = tokenRequirement as RecipientServiceModelSecurityTokenRequirement;
- if (recipientRequirement == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateAuthenticatorForRequirement, tokenRequirement)));
- }
- if (tokenType == SecurityTokenTypes.X509Certificate)
- {
- result = CreateClientX509TokenAuthenticator();
- }
- else if (tokenType == SecurityTokenTypes.Kerberos)
- {
- result = new KerberosSecurityTokenAuthenticatorWrapper(
- new KerberosSecurityTokenAuthenticator(parent.WindowsAuthentication.IncludeWindowsGroups));
- }
- else if (tokenType == SecurityTokenTypes.UserName)
- {
- if (parent.UserNameAuthentication.UserNamePasswordValidationMode == UserNamePasswordValidationMode.Windows)
- {
- if (parent.UserNameAuthentication.CacheLogonTokens)
- {
- result = new WindowsUserNameCachingSecurityTokenAuthenticator(parent.UserNameAuthentication.IncludeWindowsGroups,
- parent.UserNameAuthentication.MaxCachedLogonTokens, parent.UserNameAuthentication.CachedLogonTokenLifetime);
- }
- else
- {
- result = new WindowsUserNameSecurityTokenAuthenticator(parent.UserNameAuthentication.IncludeWindowsGroups);
- }
- }
- else
- {
- result = new CustomUserNameSecurityTokenAuthenticator(parent.UserNameAuthentication.GetUserNamePasswordValidator());
- }
- }
- else if (tokenType == SecurityTokenTypes.Rsa)
- {
- result = new RsaSecurityTokenAuthenticator();
- }
- else if (tokenType == ServiceModelSecurityTokenTypes.AnonymousSslnego)
- {
- result = CreateTlsnegoSecurityTokenAuthenticator(recipientRequirement, false, out outOfBandTokenResolver);
- }
- else if (tokenType == ServiceModelSecurityTokenTypes.MutualSslnego)
- {
- result = CreateTlsnegoSecurityTokenAuthenticator(recipientRequirement, true, out outOfBandTokenResolver);
- }
- else if (tokenType == ServiceModelSecurityTokenTypes.Spnego)
- {
- result = CreateSpnegoSecurityTokenAuthenticator(recipientRequirement, out outOfBandTokenResolver);
- }
- else if (tokenType == ServiceModelSecurityTokenTypes.SecureConversation)
- {
- result = CreateSecureConversationTokenAuthenticator(recipientRequirement, false, out outOfBandTokenResolver);
- }
- else if ((tokenType == SecurityTokenTypes.Saml)
- || (tokenType == SecurityXXX2005Strings.SamlTokenType)
- || (tokenType == SecurityJan2004Strings.SamlUri)
- || (tokenType == null && IsIssuedSecurityTokenRequirement(recipientRequirement)))
- {
- result = CreateSamlTokenAuthenticator(recipientRequirement, out outOfBandTokenResolver);
- }
- if (result == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateAuthenticatorForRequirement, tokenRequirement)));
- return result;
- }
- SecurityTokenProvider CreateLocalSecurityTokenProvider(RecipientServiceModelSecurityTokenRequirement recipientRequirement)
- {
- string tokenType = recipientRequirement.TokenType;
- SecurityTokenProvider result = null;
- if (tokenType == SecurityTokenTypes.X509Certificate)
- {
- result = CreateServerX509TokenProvider();
- }
- else if (tokenType == ServiceModelSecurityTokenTypes.SspiCredential)
- {
- // if Transport Security, AuthenicationSchemes.Basic will look at parent.UserNameAuthentication settings.
- AuthenticationSchemes authenticationScheme;
- bool authenticationSchemeIdentified = recipientRequirement.TryGetProperty<AuthenticationSchemes>(ServiceModelSecurityTokenRequirement.HttpAuthenticationSchemeProperty, out authenticationScheme);
- if (authenticationSchemeIdentified &&
- authenticationScheme.IsSet(AuthenticationSchemes.Basic) &&
- authenticationScheme.IsNotSet(AuthenticationSchemes.Digest | AuthenticationSchemes.Ntlm | AuthenticationSchemes.Negotiate))
- {
- // create security token provider even when basic and Anonymous are enabled.
- result = new SspiSecurityTokenProvider(null, parent.UserNameAuthentication.IncludeWindowsGroups, false);
- }
- else
- {
- if (authenticationSchemeIdentified &&
- authenticationScheme.IsSet(AuthenticationSchemes.Basic) &&
- parent.WindowsAuthentication.IncludeWindowsGroups != parent.UserNameAuthentication.IncludeWindowsGroups)
- {
- // Ensure there are no inconsistencies when Basic and (Digest and/or Ntlm and/or Negotiate) are both enabled
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenProviderIncludeWindowsGroupsInconsistent,
- (AuthenticationSchemes)authenticationScheme - AuthenticationSchemes.Basic,
- parent.UserNameAuthentication.IncludeWindowsGroups,
- parent.WindowsAuthentication.IncludeWindowsGroups)));
- }
- result = new SspiSecurityTokenProvider(null, parent.WindowsAuthentication.IncludeWindowsGroups, parent.WindowsAuthentication.AllowAnonymousLogons);
- }
- }
- return result;
- }
- SecurityTokenProvider CreateUncorrelatedDuplexSecurityTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
- {
- string tokenType = initiatorRequirement.TokenType;
- SecurityTokenProvider result = null;
- if (tokenType == SecurityTokenTypes.X509Certificate)
- {
- SecurityKeyUsage keyUsage = initiatorRequirement.KeyUsage;
- if (keyUsage == SecurityKeyUsage.Exchange)
- {
- if (parent.ClientCertificate.Certificate == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ClientCertificateNotProvidedOnServiceCredentials)));
- }
- result = new X509SecurityTokenProvider(parent.ClientCertificate.Certificate);
- }
- else
- {
- // this is a request for the server's own cert for signing
- result = CreateServerX509TokenProvider();
- }
- }
- return result;
- }
- public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement requirement)
- {
- if (requirement == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requirement");
- }
- RecipientServiceModelSecurityTokenRequirement recipientRequirement = requirement as RecipientServiceModelSecurityTokenRequirement;
- SecurityTokenProvider result = null;
- if (recipientRequirement != null)
- {
- result = CreateLocalSecurityTokenProvider(recipientRequirement);
- }
- else if (requirement is InitiatorServiceModelSecurityTokenRequirement)
- {
- result = CreateUncorrelatedDuplexSecurityTokenProvider((InitiatorServiceModelSecurityTokenRequirement)requirement);
- }
- if (result == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateProviderForRequirement, requirement)));
- }
- return result;
- }
- public virtual EndpointIdentity GetIdentityOfSelf(SecurityTokenRequirement tokenRequirement)
- {
- if (tokenRequirement == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenRequirement");
- }
- if (tokenRequirement is RecipientServiceModelSecurityTokenRequirement)
- {
- string tokenType = tokenRequirement.TokenType;
- if (tokenType == SecurityTokenTypes.X509Certificate
- || tokenType == ServiceModelSecurityTokenTypes.AnonymousSslnego
- || tokenType == ServiceModelSecurityTokenTypes.MutualSslnego)
- {
- if (parent.ServiceCertificate.Certificate != null)
- {
- return EndpointIdentity.CreateX509CertificateIdentity(parent.ServiceCertificate.Certificate);
- }
- }
- else if (tokenType == SecurityTokenTypes.Kerberos || tokenType == ServiceModelSecurityTokenTypes.Spnego)
- {
- return SecurityUtils.CreateWindowsIdentity();
- }
- else if (tokenType == ServiceModelSecurityTokenTypes.SecureConversation)
- {
- SecurityBindingElement securityBindingElement = ((RecipientServiceModelSecurityTokenRequirement)tokenRequirement).SecureConversationSecurityBindingElement;
- if (securityBindingElement != null)
- {
- if (securityBindingElement == null || securityBindingElement is TransportSecurityBindingElement)
- {
- return null;
- }
- SecurityTokenParameters bootstrapProtectionParameters = (securityBindingElement is SymmetricSecurityBindingElement) ? ((SymmetricSecurityBindingElement)securityBindingElement).ProtectionTokenParameters : ((AsymmetricSecurityBindingElement)securityBindingElement).RecipientTokenParameters;
- SecurityTokenRequirement bootstrapRequirement = new RecipientServiceModelSecurityTokenRequirement();
- bootstrapProtectionParameters.InitializeSecurityTokenRequirement(bootstrapRequirement);
- return GetIdentityOfSelf(bootstrapRequirement);
- }
- }
- }
- return null;
- }
- internal class KerberosSecurityTokenAuthenticatorWrapper : CommunicationObjectSecurityTokenAuthenticator
- {
- KerberosSecurityTokenAuthenticator innerAuthenticator;
- System.IdentityModel.SafeFreeCredentials credentialsHandle = null;
- public KerberosSecurityTokenAuthenticatorWrapper(KerberosSecurityTokenAuthenticator innerAuthenticator)
- {
- this.innerAuthenticator = innerAuthenticator;
- }
- public override void OnOpening()
- {
- base.OnOpening();
- if (this.credentialsHandle == null)
- {
- this.credentialsHandle = SecurityUtils.GetCredentialsHandle("Kerberos", null, true);
- }
- }
- public override void OnClose(TimeSpan timeout)
- {
- base.OnClose(timeout);
- FreeCredentialsHandle();
- }
- public override void OnAbort()
- {
- base.OnAbort();
- FreeCredentialsHandle();
- }
- void FreeCredentialsHandle()
- {
- if (this.credentialsHandle != null)
- {
- this.credentialsHandle.Close();
- this.credentialsHandle = null;
- }
- }
- protected override bool CanValidateTokenCore(SecurityToken token)
- {
- return this.innerAuthenticator.CanValidateToken(token);
- }
- internal ReadOnlyCollection<IAuthorizationPolicy> ValidateToken(SecurityToken token, ChannelBinding channelBinding, ExtendedProtectionPolicy protectionPolicy)
- {
- KerberosReceiverSecurityToken kerberosToken = (KerberosReceiverSecurityToken)token;
- kerberosToken.Initialize(this.credentialsHandle, channelBinding, protectionPolicy);
- return this.innerAuthenticator.ValidateToken(kerberosToken);
- }
- protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateTokenCore(SecurityToken token)
- {
- return ValidateToken(token, null, null);
- }
- }
- }
- }
|