1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4 
5 namespace System.ServiceModel.Security
6 {
7     using System.Collections.Generic;
8     using System.Collections.ObjectModel;
9     using System.IdentityModel.Policy;
10     using System.IdentityModel.Selectors;
11     using System.IdentityModel.Tokens;
12     using System.Net;
13     using System.Security.Authentication.ExtendedProtection;
14     using System.ServiceModel;
15     using System.ServiceModel.Channels;
16     using System.ServiceModel.Description;
17     using System.ServiceModel.Dispatcher;
18     using System.ServiceModel.Security.Tokens;
19 
20     public class ServiceCredentialsSecurityTokenManager : SecurityTokenManager, IEndpointIdentityProvider
21     {
22         ServiceCredentials parent;
23 
ServiceCredentialsSecurityTokenManager(ServiceCredentials parent)24         public ServiceCredentialsSecurityTokenManager(ServiceCredentials parent)
25         {
26             if (parent == null)
27             {
28                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parent");
29             }
30             this.parent = parent;
31         }
32 
33         public ServiceCredentials ServiceCredentials
34         {
35             get { return parent; }
36         }
37 
CreateSecurityTokenSerializer(SecurityTokenVersion version)38         public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
39         {
40             if (version == null)
41             {
42                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version");
43             }
44             MessageSecurityTokenVersion wsVersion = version as MessageSecurityTokenVersion;
45             if (wsVersion != null)
46             {
47                 SamlSerializer samlSerializer = null;
48                 if (parent.IssuedTokenAuthentication != null)
49                     samlSerializer = parent.IssuedTokenAuthentication.SamlSerializer;
50                 else
51                     samlSerializer = new SamlSerializer();
52 
53                 return new WSSecurityTokenSerializer(wsVersion.SecurityVersion, wsVersion.TrustVersion, wsVersion.SecureConversationVersion, wsVersion.EmitBspRequiredAttributes, samlSerializer, parent.SecureConversationAuthentication.SecurityStateEncoder, parent.SecureConversationAuthentication.SecurityContextClaimTypes);
54             }
55             else
56             {
57                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateSerializerForVersion, version)));
58             }
59         }
60 
CreateSecureConversationTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, bool preserveBootstrapTokens, out SecurityTokenResolver sctResolver)61         protected SecurityTokenAuthenticator CreateSecureConversationTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, bool preserveBootstrapTokens, out SecurityTokenResolver sctResolver)
62         {
63             SecurityBindingElement securityBindingElement = recipientRequirement.SecurityBindingElement;
64             if (securityBindingElement == null)
65             {
66                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenAuthenticatorRequiresSecurityBindingElement, recipientRequirement));
67             }
68             bool isCookieMode = !recipientRequirement.SupportSecurityContextCancellation;
69             LocalServiceSecuritySettings localServiceSettings = securityBindingElement.LocalServiceSettings;
70             IMessageFilterTable<EndpointAddress> endpointFilterTable = recipientRequirement.GetPropertyOrDefault<IMessageFilterTable<EndpointAddress>>(ServiceModelSecurityTokenRequirement.EndpointFilterTableProperty, null);
71 
72             if (!isCookieMode)
73             {
74                 sctResolver = new SecurityContextSecurityTokenResolver(Int32.MaxValue, false);
75 
76                 // remember this authenticator for future reference
77                 SecuritySessionSecurityTokenAuthenticator authenticator = new SecuritySessionSecurityTokenAuthenticator();
78                 authenticator.BootstrapSecurityBindingElement = SecurityUtils.GetIssuerSecurityBindingElement(recipientRequirement);
79                 authenticator.IssuedSecurityTokenParameters = recipientRequirement.GetProperty<SecurityTokenParameters>(ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty);
80                 authenticator.IssuedTokenCache = (ISecurityContextSecurityTokenCache)sctResolver;
81                 authenticator.IssuerBindingContext = recipientRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
82                 authenticator.KeyEntropyMode = securityBindingElement.KeyEntropyMode;
83                 authenticator.ListenUri = recipientRequirement.ListenUri;
84                 authenticator.SecurityAlgorithmSuite = recipientRequirement.SecurityAlgorithmSuite;
85                 authenticator.SessionTokenLifetime = TimeSpan.MaxValue;
86                 authenticator.KeyRenewalInterval = securityBindingElement.LocalServiceSettings.SessionKeyRenewalInterval;
87                 authenticator.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(recipientRequirement, this);
88                 authenticator.EndpointFilterTable = endpointFilterTable;
89                 authenticator.MaximumConcurrentNegotiations = localServiceSettings.MaxStatefulNegotiations;
90                 authenticator.NegotiationTimeout = localServiceSettings.NegotiationTimeout;
91                 authenticator.PreserveBootstrapTokens = preserveBootstrapTokens;
92                 return authenticator;
93             }
94             else
95             {
96                 sctResolver = new SecurityContextSecurityTokenResolver(localServiceSettings.MaxCachedCookies, true, localServiceSettings.MaxClockSkew);
97 
98                 AcceleratedTokenAuthenticator authenticator = new AcceleratedTokenAuthenticator();
99                 authenticator.BootstrapSecurityBindingElement = SecurityUtils.GetIssuerSecurityBindingElement(recipientRequirement);
100                 authenticator.KeyEntropyMode = securityBindingElement.KeyEntropyMode;
101                 authenticator.EncryptStateInServiceToken = true;
102                 authenticator.IssuedSecurityTokenParameters = recipientRequirement.GetProperty<SecurityTokenParameters>(ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty);
103                 authenticator.IssuedTokenCache = (ISecurityContextSecurityTokenCache)sctResolver;
104                 authenticator.IssuerBindingContext = recipientRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
105                 authenticator.ListenUri = recipientRequirement.ListenUri;
106                 authenticator.SecurityAlgorithmSuite = recipientRequirement.SecurityAlgorithmSuite;
107                 authenticator.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(recipientRequirement, this);
108                 authenticator.SecurityStateEncoder = parent.SecureConversationAuthentication.SecurityStateEncoder;
109                 authenticator.KnownTypes = parent.SecureConversationAuthentication.SecurityContextClaimTypes;
110                 authenticator.PreserveBootstrapTokens = preserveBootstrapTokens;
111 
112                 // local security quotas
113                 authenticator.MaximumCachedNegotiationState = localServiceSettings.MaxStatefulNegotiations;
114                 authenticator.NegotiationTimeout = localServiceSettings.NegotiationTimeout;
115                 authenticator.ServiceTokenLifetime = localServiceSettings.IssuedCookieLifetime;
116                 authenticator.MaximumConcurrentNegotiations = localServiceSettings.MaxStatefulNegotiations;
117 
118                 // audit settings
119                 authenticator.AuditLogLocation = recipientRequirement.AuditLogLocation;
120                 authenticator.SuppressAuditFailure = recipientRequirement.SuppressAuditFailure;
121                 authenticator.MessageAuthenticationAuditLevel = recipientRequirement.MessageAuthenticationAuditLevel;
122                 authenticator.EndpointFilterTable = endpointFilterTable;
123                 return authenticator;
124             }
125         }
126 
CreateSpnegoSecurityTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, out SecurityTokenResolver sctResolver)127         SecurityTokenAuthenticator CreateSpnegoSecurityTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, out SecurityTokenResolver sctResolver)
128         {
129             SecurityBindingElement securityBindingElement = recipientRequirement.SecurityBindingElement;
130             if (securityBindingElement == null)
131             {
132                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenAuthenticatorRequiresSecurityBindingElement, recipientRequirement));
133             }
134             bool isCookieMode = !recipientRequirement.SupportSecurityContextCancellation;
135             LocalServiceSecuritySettings localServiceSettings = securityBindingElement.LocalServiceSettings;
136             sctResolver = new SecurityContextSecurityTokenResolver(localServiceSettings.MaxCachedCookies, true);
137             ExtendedProtectionPolicy extendedProtectionPolicy = null;
138             recipientRequirement.TryGetProperty<ExtendedProtectionPolicy>(ServiceModelSecurityTokenRequirement.ExtendedProtectionPolicy, out extendedProtectionPolicy);
139 
140             SpnegoTokenAuthenticator authenticator = new SpnegoTokenAuthenticator();
141             authenticator.ExtendedProtectionPolicy = extendedProtectionPolicy;
142             authenticator.AllowUnauthenticatedCallers = parent.WindowsAuthentication.AllowAnonymousLogons;
143             authenticator.ExtractGroupsForWindowsAccounts = parent.WindowsAuthentication.IncludeWindowsGroups;
144             authenticator.IsClientAnonymous = false;
145             authenticator.EncryptStateInServiceToken = isCookieMode;
146             authenticator.IssuedSecurityTokenParameters = recipientRequirement.GetProperty<SecurityTokenParameters>(ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty);
147             authenticator.IssuedTokenCache = (ISecurityContextSecurityTokenCache)sctResolver;
148             authenticator.IssuerBindingContext = recipientRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
149             authenticator.ListenUri = recipientRequirement.ListenUri;
150             authenticator.SecurityAlgorithmSuite = recipientRequirement.SecurityAlgorithmSuite;
151             authenticator.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(recipientRequirement, this);
152             authenticator.SecurityStateEncoder = parent.SecureConversationAuthentication.SecurityStateEncoder;
153             authenticator.KnownTypes = parent.SecureConversationAuthentication.SecurityContextClaimTypes;
154             // 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.
155             if (securityBindingElement is TransportSecurityBindingElement)
156             {
157                 authenticator.MaxMessageSize = SecurityUtils.GetMaxNegotiationBufferSize(authenticator.IssuerBindingContext);
158             }
159 
160             // local security quotas
161             authenticator.MaximumCachedNegotiationState = localServiceSettings.MaxStatefulNegotiations;
162             authenticator.NegotiationTimeout = localServiceSettings.NegotiationTimeout;
163             authenticator.ServiceTokenLifetime = localServiceSettings.IssuedCookieLifetime;
164             authenticator.MaximumConcurrentNegotiations = localServiceSettings.MaxStatefulNegotiations;
165 
166             // audit settings
167             authenticator.AuditLogLocation = recipientRequirement.AuditLogLocation;
168             authenticator.SuppressAuditFailure = recipientRequirement.SuppressAuditFailure;
169             authenticator.MessageAuthenticationAuditLevel = recipientRequirement.MessageAuthenticationAuditLevel;
170             return authenticator;
171         }
172 
CreateTlsnegoClientX509TokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement)173         SecurityTokenAuthenticator CreateTlsnegoClientX509TokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement)
174         {
175             RecipientServiceModelSecurityTokenRequirement clientX509Requirement = new RecipientServiceModelSecurityTokenRequirement();
176             clientX509Requirement.TokenType = SecurityTokenTypes.X509Certificate;
177             clientX509Requirement.KeyUsage = SecurityKeyUsage.Signature;
178             clientX509Requirement.ListenUri = recipientRequirement.ListenUri;
179             clientX509Requirement.KeyType = SecurityKeyType.AsymmetricKey;
180             clientX509Requirement.SecurityBindingElement = recipientRequirement.SecurityBindingElement;
181             SecurityTokenResolver dummy;
182             return this.CreateSecurityTokenAuthenticator(clientX509Requirement, out dummy);
183         }
184 
CreateTlsnegoServerX509TokenProvider(RecipientServiceModelSecurityTokenRequirement recipientRequirement)185         SecurityTokenProvider CreateTlsnegoServerX509TokenProvider(RecipientServiceModelSecurityTokenRequirement recipientRequirement)
186         {
187             RecipientServiceModelSecurityTokenRequirement serverX509Requirement = new RecipientServiceModelSecurityTokenRequirement();
188             serverX509Requirement.TokenType = SecurityTokenTypes.X509Certificate;
189             serverX509Requirement.KeyUsage = SecurityKeyUsage.Exchange;
190             serverX509Requirement.ListenUri = recipientRequirement.ListenUri;
191             serverX509Requirement.KeyType = SecurityKeyType.AsymmetricKey;
192             serverX509Requirement.SecurityBindingElement = recipientRequirement.SecurityBindingElement;
193             return this.CreateSecurityTokenProvider(serverX509Requirement);
194         }
195 
CreateTlsnegoSecurityTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, bool requireClientCertificate, out SecurityTokenResolver sctResolver)196         SecurityTokenAuthenticator CreateTlsnegoSecurityTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, bool requireClientCertificate, out SecurityTokenResolver sctResolver)
197         {
198             SecurityBindingElement securityBindingElement = recipientRequirement.SecurityBindingElement;
199             if (securityBindingElement == null)
200             {
201                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenAuthenticatorRequiresSecurityBindingElement, recipientRequirement));
202             }
203             bool isCookieMode = !recipientRequirement.SupportSecurityContextCancellation;
204             LocalServiceSecuritySettings localServiceSettings = securityBindingElement.LocalServiceSettings;
205             sctResolver = new SecurityContextSecurityTokenResolver(localServiceSettings.MaxCachedCookies, true);
206 
207             TlsnegoTokenAuthenticator authenticator = new TlsnegoTokenAuthenticator();
208             authenticator.IsClientAnonymous = !requireClientCertificate;
209             if (requireClientCertificate)
210             {
211                 authenticator.ClientTokenAuthenticator = this.CreateTlsnegoClientX509TokenAuthenticator(recipientRequirement);
212                 authenticator.MapCertificateToWindowsAccount = this.ServiceCredentials.ClientCertificate.Authentication.MapClientCertificateToWindowsAccount;
213             }
214             authenticator.EncryptStateInServiceToken = isCookieMode;
215             authenticator.IssuedSecurityTokenParameters = recipientRequirement.GetProperty<SecurityTokenParameters>(ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty);
216             authenticator.IssuedTokenCache = (ISecurityContextSecurityTokenCache)sctResolver;
217             authenticator.IssuerBindingContext = recipientRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
218             authenticator.ListenUri = recipientRequirement.ListenUri;
219             authenticator.SecurityAlgorithmSuite = recipientRequirement.SecurityAlgorithmSuite;
220             authenticator.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(recipientRequirement, this);
221             authenticator.SecurityStateEncoder = parent.SecureConversationAuthentication.SecurityStateEncoder;
222             authenticator.KnownTypes = parent.SecureConversationAuthentication.SecurityContextClaimTypes;
223             authenticator.ServerTokenProvider = CreateTlsnegoServerX509TokenProvider(recipientRequirement);
224             // local security quotas
225             authenticator.MaximumCachedNegotiationState = localServiceSettings.MaxStatefulNegotiations;
226             authenticator.NegotiationTimeout = localServiceSettings.NegotiationTimeout;
227             authenticator.ServiceTokenLifetime = localServiceSettings.IssuedCookieLifetime;
228             authenticator.MaximumConcurrentNegotiations = localServiceSettings.MaxStatefulNegotiations;
229             // 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.
230             if (securityBindingElement is TransportSecurityBindingElement)
231             {
232                 authenticator.MaxMessageSize = SecurityUtils.GetMaxNegotiationBufferSize(authenticator.IssuerBindingContext);
233             }
234             // audit settings
235             authenticator.AuditLogLocation = recipientRequirement.AuditLogLocation;
236             authenticator.SuppressAuditFailure = recipientRequirement.SuppressAuditFailure;
237             authenticator.MessageAuthenticationAuditLevel = recipientRequirement.MessageAuthenticationAuditLevel;
238             return authenticator;
239         }
240 
CreateClientX509TokenAuthenticator()241         X509SecurityTokenAuthenticator CreateClientX509TokenAuthenticator()
242         {
243             X509ClientCertificateAuthentication authentication = parent.ClientCertificate.Authentication;
244             return new X509SecurityTokenAuthenticator(authentication.GetCertificateValidator(), authentication.MapClientCertificateToWindowsAccount, authentication.IncludeWindowsGroups);
245         }
246 
CreateSamlTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, out SecurityTokenResolver outOfBandTokenResolver)247         SamlSecurityTokenAuthenticator CreateSamlTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, out SecurityTokenResolver outOfBandTokenResolver)
248         {
249             if (recipientRequirement == null)
250                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("recipientRequirement");
251 
252             Collection<SecurityToken> outOfBandTokens = new Collection<SecurityToken>();
253             if (parent.ServiceCertificate.Certificate != null)
254             {
255                 outOfBandTokens.Add(new X509SecurityToken(parent.ServiceCertificate.Certificate));
256             }
257             List<SecurityTokenAuthenticator> supportingAuthenticators = new List<SecurityTokenAuthenticator>();
258             if ((parent.IssuedTokenAuthentication.KnownCertificates != null) && (parent.IssuedTokenAuthentication.KnownCertificates.Count > 0))
259             {
260                 for (int i = 0; i < parent.IssuedTokenAuthentication.KnownCertificates.Count; ++i)
261                 {
262                     outOfBandTokens.Add(new X509SecurityToken(parent.IssuedTokenAuthentication.KnownCertificates[i]));
263                 }
264             }
265 
266             X509CertificateValidator validator = parent.IssuedTokenAuthentication.GetCertificateValidator();
267             supportingAuthenticators.Add(new X509SecurityTokenAuthenticator(validator));
268 
269             if (parent.IssuedTokenAuthentication.AllowUntrustedRsaIssuers)
270             {
271                 supportingAuthenticators.Add(new RsaSecurityTokenAuthenticator());
272             }
273 
274             outOfBandTokenResolver = (outOfBandTokens.Count > 0) ? SecurityTokenResolver.CreateDefaultSecurityTokenResolver(new ReadOnlyCollection<SecurityToken>(outOfBandTokens), false) : null;
275 
276             SamlSecurityTokenAuthenticator ssta;
277 
278             if ((recipientRequirement.SecurityBindingElement == null) || (recipientRequirement.SecurityBindingElement.LocalServiceSettings == null))
279             {
280                 ssta = new SamlSecurityTokenAuthenticator(supportingAuthenticators);
281             }
282             else
283             {
284                 ssta = new SamlSecurityTokenAuthenticator(supportingAuthenticators, recipientRequirement.SecurityBindingElement.LocalServiceSettings.MaxClockSkew);
285             }
286 
287             // set audience uri restrictions
288             ssta.AudienceUriMode = parent.IssuedTokenAuthentication.AudienceUriMode;
289             IList<string> allowedAudienceUris = ssta.AllowedAudienceUris;
290             if (parent.IssuedTokenAuthentication.AllowedAudienceUris != null)
291             {
292                 for (int i = 0; i < parent.IssuedTokenAuthentication.AllowedAudienceUris.Count; i++)
293                     allowedAudienceUris.Add(parent.IssuedTokenAuthentication.AllowedAudienceUris[i]);
294             }
295 
296             if (recipientRequirement.ListenUri != null)
297             {
298                 allowedAudienceUris.Add(recipientRequirement.ListenUri.AbsoluteUri);
299             }
300 
301             return ssta;
302         }
303 
CreateServerX509TokenProvider()304         X509SecurityTokenProvider CreateServerX509TokenProvider()
305         {
306             if (parent.ServiceCertificate.Certificate == null)
307             {
308                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ServiceCertificateNotProvidedOnServiceCredentials)));
309             }
310             SecurityUtils.EnsureCertificateCanDoKeyExchange(parent.ServiceCertificate.Certificate);
311             return new ServiceX509SecurityTokenProvider(parent.ServiceCertificate.Certificate);
312         }
313 
IsIssuedSecurityTokenRequirement(SecurityTokenRequirement requirement)314         protected bool IsIssuedSecurityTokenRequirement(SecurityTokenRequirement requirement)
315         {
316             return (requirement != null && requirement.Properties.ContainsKey(ServiceModelSecurityTokenRequirement.IssuerAddressProperty));
317         }
318 
CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)319         public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
320         {
321             if (tokenRequirement == null)
322             {
323                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenRequirement");
324             }
325             string tokenType = tokenRequirement.TokenType;
326             outOfBandTokenResolver = null;
327             SecurityTokenAuthenticator result = null;
328             if (tokenRequirement is InitiatorServiceModelSecurityTokenRequirement)
329             {
330                 // this is the uncorrelated duplex case in which the server is asking for
331                 // an authenticator to validate its provisioned client certificate
332                 if (tokenType == SecurityTokenTypes.X509Certificate && tokenRequirement.KeyUsage == SecurityKeyUsage.Exchange)
333                 {
334                     return new X509SecurityTokenAuthenticator(X509CertificateValidator.None, false);
335                 }
336             }
337 
338             RecipientServiceModelSecurityTokenRequirement recipientRequirement = tokenRequirement as RecipientServiceModelSecurityTokenRequirement;
339             if (recipientRequirement == null)
340             {
341                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateAuthenticatorForRequirement, tokenRequirement)));
342             }
343             if (tokenType == SecurityTokenTypes.X509Certificate)
344             {
345                 result = CreateClientX509TokenAuthenticator();
346             }
347             else if (tokenType == SecurityTokenTypes.Kerberos)
348             {
349                 result = new KerberosSecurityTokenAuthenticatorWrapper(
350                     new KerberosSecurityTokenAuthenticator(parent.WindowsAuthentication.IncludeWindowsGroups));
351             }
352             else if (tokenType == SecurityTokenTypes.UserName)
353             {
354                 if (parent.UserNameAuthentication.UserNamePasswordValidationMode == UserNamePasswordValidationMode.Windows)
355                 {
356                     if (parent.UserNameAuthentication.CacheLogonTokens)
357                     {
358                         result = new WindowsUserNameCachingSecurityTokenAuthenticator(parent.UserNameAuthentication.IncludeWindowsGroups,
359                             parent.UserNameAuthentication.MaxCachedLogonTokens, parent.UserNameAuthentication.CachedLogonTokenLifetime);
360                     }
361                     else
362                     {
363                         result = new WindowsUserNameSecurityTokenAuthenticator(parent.UserNameAuthentication.IncludeWindowsGroups);
364                     }
365                 }
366                 else
367                 {
368                     result = new CustomUserNameSecurityTokenAuthenticator(parent.UserNameAuthentication.GetUserNamePasswordValidator());
369                 }
370             }
371             else if (tokenType == SecurityTokenTypes.Rsa)
372             {
373                 result = new RsaSecurityTokenAuthenticator();
374             }
375             else if (tokenType == ServiceModelSecurityTokenTypes.AnonymousSslnego)
376             {
377                 result = CreateTlsnegoSecurityTokenAuthenticator(recipientRequirement, false, out outOfBandTokenResolver);
378             }
379             else if (tokenType == ServiceModelSecurityTokenTypes.MutualSslnego)
380             {
381                 result = CreateTlsnegoSecurityTokenAuthenticator(recipientRequirement, true, out outOfBandTokenResolver);
382             }
383             else if (tokenType == ServiceModelSecurityTokenTypes.Spnego)
384             {
385                 result = CreateSpnegoSecurityTokenAuthenticator(recipientRequirement, out outOfBandTokenResolver);
386             }
387             else if (tokenType == ServiceModelSecurityTokenTypes.SecureConversation)
388             {
389                 result = CreateSecureConversationTokenAuthenticator(recipientRequirement, false, out outOfBandTokenResolver);
390             }
391             else if ((tokenType == SecurityTokenTypes.Saml)
392                 || (tokenType == SecurityXXX2005Strings.SamlTokenType)
393                 || (tokenType == SecurityJan2004Strings.SamlUri)
394                 || (tokenType == null && IsIssuedSecurityTokenRequirement(recipientRequirement)))
395             {
396                 result = CreateSamlTokenAuthenticator(recipientRequirement, out outOfBandTokenResolver);
397             }
398 
399             if (result == null)
400                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateAuthenticatorForRequirement, tokenRequirement)));
401 
402             return result;
403         }
404 
CreateLocalSecurityTokenProvider(RecipientServiceModelSecurityTokenRequirement recipientRequirement)405         SecurityTokenProvider CreateLocalSecurityTokenProvider(RecipientServiceModelSecurityTokenRequirement recipientRequirement)
406         {
407             string tokenType = recipientRequirement.TokenType;
408             SecurityTokenProvider result = null;
409             if (tokenType == SecurityTokenTypes.X509Certificate)
410             {
411                 result = CreateServerX509TokenProvider();
412             }
413             else if (tokenType == ServiceModelSecurityTokenTypes.SspiCredential)
414             {
415                 // if Transport Security, AuthenicationSchemes.Basic will look at parent.UserNameAuthentication settings.
416                 AuthenticationSchemes authenticationScheme;
417                 bool authenticationSchemeIdentified = recipientRequirement.TryGetProperty<AuthenticationSchemes>(ServiceModelSecurityTokenRequirement.HttpAuthenticationSchemeProperty, out authenticationScheme);
418                 if (authenticationSchemeIdentified &&
419                     authenticationScheme.IsSet(AuthenticationSchemes.Basic) &&
420                     authenticationScheme.IsNotSet(AuthenticationSchemes.Digest | AuthenticationSchemes.Ntlm | AuthenticationSchemes.Negotiate))
421                 {
422                     // create security token provider even when basic and Anonymous are enabled.
423                     result = new SspiSecurityTokenProvider(null, parent.UserNameAuthentication.IncludeWindowsGroups, false);
424                 }
425                 else
426                 {
427                     if (authenticationSchemeIdentified &&
428                        authenticationScheme.IsSet(AuthenticationSchemes.Basic) &&
429                        parent.WindowsAuthentication.IncludeWindowsGroups != parent.UserNameAuthentication.IncludeWindowsGroups)
430                     {
431                         // Ensure there are no inconsistencies when Basic and (Digest and/or Ntlm and/or Negotiate) are both enabled
432                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenProviderIncludeWindowsGroupsInconsistent,
433                             (AuthenticationSchemes)authenticationScheme - AuthenticationSchemes.Basic,
434                             parent.UserNameAuthentication.IncludeWindowsGroups,
435                             parent.WindowsAuthentication.IncludeWindowsGroups)));
436                     }
437 
438                     result = new SspiSecurityTokenProvider(null, parent.WindowsAuthentication.IncludeWindowsGroups, parent.WindowsAuthentication.AllowAnonymousLogons);
439                 }
440             }
441             return result;
442         }
443 
CreateUncorrelatedDuplexSecurityTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)444         SecurityTokenProvider CreateUncorrelatedDuplexSecurityTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
445         {
446             string tokenType = initiatorRequirement.TokenType;
447             SecurityTokenProvider result = null;
448             if (tokenType == SecurityTokenTypes.X509Certificate)
449             {
450                 SecurityKeyUsage keyUsage = initiatorRequirement.KeyUsage;
451                 if (keyUsage == SecurityKeyUsage.Exchange)
452                 {
453                     if (parent.ClientCertificate.Certificate == null)
454                     {
455                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ClientCertificateNotProvidedOnServiceCredentials)));
456                     }
457 
458                     result = new X509SecurityTokenProvider(parent.ClientCertificate.Certificate);
459                 }
460                 else
461                 {
462                     // this is a request for the server's own cert for signing
463                     result = CreateServerX509TokenProvider();
464                 }
465             }
466             return result;
467         }
468 
CreateSecurityTokenProvider(SecurityTokenRequirement requirement)469         public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement requirement)
470         {
471             if (requirement == null)
472             {
473                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requirement");
474             }
475 
476             RecipientServiceModelSecurityTokenRequirement recipientRequirement = requirement as RecipientServiceModelSecurityTokenRequirement;
477             SecurityTokenProvider result = null;
478             if (recipientRequirement != null)
479             {
480                 result = CreateLocalSecurityTokenProvider(recipientRequirement);
481             }
482             else if (requirement is InitiatorServiceModelSecurityTokenRequirement)
483             {
484                 result = CreateUncorrelatedDuplexSecurityTokenProvider((InitiatorServiceModelSecurityTokenRequirement)requirement);
485             }
486 
487             if (result == null)
488             {
489                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateProviderForRequirement, requirement)));
490             }
491             return result;
492         }
493 
GetIdentityOfSelf(SecurityTokenRequirement tokenRequirement)494         public virtual EndpointIdentity GetIdentityOfSelf(SecurityTokenRequirement tokenRequirement)
495         {
496             if (tokenRequirement == null)
497             {
498                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenRequirement");
499             }
500             if (tokenRequirement is RecipientServiceModelSecurityTokenRequirement)
501             {
502                 string tokenType = tokenRequirement.TokenType;
503                 if (tokenType == SecurityTokenTypes.X509Certificate
504                     || tokenType == ServiceModelSecurityTokenTypes.AnonymousSslnego
505                     || tokenType == ServiceModelSecurityTokenTypes.MutualSslnego)
506                 {
507                     if (parent.ServiceCertificate.Certificate != null)
508                     {
509                         return EndpointIdentity.CreateX509CertificateIdentity(parent.ServiceCertificate.Certificate);
510                     }
511                 }
512                 else if (tokenType == SecurityTokenTypes.Kerberos || tokenType == ServiceModelSecurityTokenTypes.Spnego)
513                 {
514                     return SecurityUtils.CreateWindowsIdentity();
515                 }
516                 else if (tokenType == ServiceModelSecurityTokenTypes.SecureConversation)
517                 {
518                     SecurityBindingElement securityBindingElement = ((RecipientServiceModelSecurityTokenRequirement)tokenRequirement).SecureConversationSecurityBindingElement;
519                     if (securityBindingElement != null)
520                     {
521                         if (securityBindingElement == null || securityBindingElement is TransportSecurityBindingElement)
522                         {
523                             return null;
524                         }
525                         SecurityTokenParameters bootstrapProtectionParameters = (securityBindingElement is SymmetricSecurityBindingElement) ? ((SymmetricSecurityBindingElement)securityBindingElement).ProtectionTokenParameters : ((AsymmetricSecurityBindingElement)securityBindingElement).RecipientTokenParameters;
526                         SecurityTokenRequirement bootstrapRequirement = new RecipientServiceModelSecurityTokenRequirement();
527                         bootstrapProtectionParameters.InitializeSecurityTokenRequirement(bootstrapRequirement);
528                         return GetIdentityOfSelf(bootstrapRequirement);
529                     }
530                 }
531             }
532             return null;
533         }
534 
535         internal class KerberosSecurityTokenAuthenticatorWrapper : CommunicationObjectSecurityTokenAuthenticator
536         {
537             KerberosSecurityTokenAuthenticator innerAuthenticator;
538             System.IdentityModel.SafeFreeCredentials credentialsHandle = null;
539 
KerberosSecurityTokenAuthenticatorWrapper(KerberosSecurityTokenAuthenticator innerAuthenticator)540             public KerberosSecurityTokenAuthenticatorWrapper(KerberosSecurityTokenAuthenticator innerAuthenticator)
541             {
542                 this.innerAuthenticator = innerAuthenticator;
543             }
544 
OnOpening()545             public override void OnOpening()
546             {
547                 base.OnOpening();
548                 if (this.credentialsHandle == null)
549                 {
550                     this.credentialsHandle = SecurityUtils.GetCredentialsHandle("Kerberos", null, true);
551                 }
552             }
553 
OnClose(TimeSpan timeout)554             public override void OnClose(TimeSpan timeout)
555             {
556                 base.OnClose(timeout);
557                 FreeCredentialsHandle();
558             }
559 
OnAbort()560             public override void OnAbort()
561             {
562                 base.OnAbort();
563                 FreeCredentialsHandle();
564             }
565 
FreeCredentialsHandle()566             void FreeCredentialsHandle()
567             {
568                 if (this.credentialsHandle != null)
569                 {
570                     this.credentialsHandle.Close();
571                     this.credentialsHandle = null;
572                 }
573             }
574 
CanValidateTokenCore(SecurityToken token)575             protected override bool CanValidateTokenCore(SecurityToken token)
576             {
577                 return this.innerAuthenticator.CanValidateToken(token);
578             }
579 
ValidateToken(SecurityToken token, ChannelBinding channelBinding, ExtendedProtectionPolicy protectionPolicy)580             internal ReadOnlyCollection<IAuthorizationPolicy> ValidateToken(SecurityToken token, ChannelBinding channelBinding, ExtendedProtectionPolicy protectionPolicy)
581             {
582                 KerberosReceiverSecurityToken kerberosToken = (KerberosReceiverSecurityToken)token;
583                 kerberosToken.Initialize(this.credentialsHandle, channelBinding, protectionPolicy);
584                 return this.innerAuthenticator.ValidateToken(kerberosToken);
585             }
586 
ValidateTokenCore(SecurityToken token)587             protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateTokenCore(SecurityToken token)
588             {
589                 return ValidateToken(token, null, null);
590             }
591         }
592     }
593 }
594