You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			929 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			929 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //------------------------------------------------------------
 | |
| // Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| //------------------------------------------------------------
 | |
| 
 | |
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Collections.ObjectModel;
 | |
| using System.Configuration;
 | |
| using System.Diagnostics;
 | |
| using System.Globalization;
 | |
| using System.IdentityModel.Diagnostics;
 | |
| using System.IdentityModel.Selectors;
 | |
| using System.IdentityModel.Tokens;
 | |
| using System.Security.Claims;
 | |
| using System.Security.Cryptography.X509Certificates;
 | |
| using System.ServiceModel.Security;
 | |
| using System.Xml;
 | |
| 
 | |
| namespace System.IdentityModel.Configuration
 | |
| {
 | |
|     /// <summary>
 | |
|     /// Defines the collection of configurable properties controlling the behavior of the Windows Identity Foundation.
 | |
|     /// </summary>
 | |
|     public class IdentityConfiguration
 | |
|     {
 | |
| #pragma warning disable 1591
 | |
|         public const string DefaultServiceName = ConfigurationStrings.DefaultServiceName;
 | |
|         public static readonly TimeSpan DefaultMaxClockSkew = new TimeSpan(0, 5, 0);
 | |
|         internal const string DefaultMaxClockSkewString = "00:05:00";
 | |
|         public static readonly X509CertificateValidationMode DefaultCertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust;
 | |
|         public static readonly Type DefaultIssuerNameRegistryType = typeof(ConfigurationBasedIssuerNameRegistry);
 | |
|         public static readonly X509RevocationMode DefaultRevocationMode = X509RevocationMode.Online;
 | |
|         public static readonly StoreLocation DefaultTrustedStoreLocation = StoreLocation.LocalMachine;
 | |
| #pragma warning restore 1591
 | |
| 
 | |
|         ClaimsAuthenticationManager _claimsAuthenticationManager = new ClaimsAuthenticationManager();
 | |
|         ClaimsAuthorizationManager _claimsAuthorizationManager = new ClaimsAuthorizationManager();
 | |
|         bool _isInitialized;
 | |
|         SecurityTokenHandlerCollectionManager _securityTokenHandlerCollectionManager;
 | |
|         string _identityConfigurationName = DefaultServiceName;
 | |
|         TimeSpan _serviceMaxClockSkew = DefaultMaxClockSkew;
 | |
|         SecurityTokenHandlerConfiguration _serviceHandlerConfiguration;
 | |
|         X509Certificate2 _serviceCertificate;
 | |
|         List<X509Certificate2> knownCertificates;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Initializes an instance of <see cref="IdentityConfiguration"/>
 | |
|         /// </summary>
 | |
|         public IdentityConfiguration()
 | |
|         {
 | |
|             SystemIdentityModelSection section = SystemIdentityModelSection.Current;
 | |
|             IdentityConfigurationElement element = (section != null) ? section.IdentityConfigurationElements.GetElement(DefaultServiceName) : null;
 | |
|             LoadConfiguration(element);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Initializes an instance of <see cref="IdentityConfiguration"/>
 | |
|         /// </summary>
 | |
|         /// <param name="serviceCertificate">The service certificate to be used in ServiceTokenResolver and SessionSecurityTokenHandler.</param>
 | |
|         public IdentityConfiguration(X509Certificate2 serviceCertificate)
 | |
|             : this()
 | |
|         {
 | |
|             this.ServiceCertificate = serviceCertificate;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Initializes an instance of <see cref="IdentityConfiguration"/>
 | |
|         /// </summary>
 | |
|         /// <param name="loadConfig">Whether or not config should be loaded.</param>
 | |
|         /// <exception cref="InvalidOperationException">Thrown if loadConfig is set to true but there is no 
 | |
|         /// <System.IdentityModel> configuration element</exception>
 | |
|         public IdentityConfiguration(bool loadConfig)
 | |
|         {
 | |
|             if (loadConfig)
 | |
|             {
 | |
|                 SystemIdentityModelSection section = SystemIdentityModelSection.Current;
 | |
| 
 | |
|                 if (section == null)
 | |
|                 {
 | |
|                     throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID7027));
 | |
|                 }
 | |
| 
 | |
|                 IdentityConfigurationElement element = section.IdentityConfigurationElements.GetElement(DefaultServiceName);
 | |
|                 LoadConfiguration(element);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 LoadConfiguration(null);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Initializes an instance of <see cref="IdentityConfiguration"/>
 | |
|         /// </summary>
 | |
|         /// <param name="loadConfig">Whether or not config should be loaded.</param>
 | |
|         /// <param name="serviceCertificate">The service certificate to be used in ServiceTokenResolver and SessionSecurityTokenHandler.</param>
 | |
|         /// <exception cref="InvalidOperationException">Thrown if loadConfig is set to true but there is no 
 | |
|         /// <System.IdentityModel> configuration element</exception>
 | |
|         public IdentityConfiguration(bool loadConfig, X509Certificate2 serviceCertificate)
 | |
|             : this(loadConfig)
 | |
|         {
 | |
|             this.ServiceCertificate = serviceCertificate;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Initializes an instance of <see cref="IdentityConfiguration"/>
 | |
|         /// </summary>
 | |
|         /// <param name="identityConfigurationName">The name of the <service> element from which configuration is to be loaded.</param>
 | |
|         /// <exception cref="InvalidOperationException">Thrown if there is no <System.IdentityModel> configuration element</exception>
 | |
|         /// <remarks>If this constructor is called then a System.IdentityModel config section with the provided name must exist.</remarks>        
 | |
|         public IdentityConfiguration(string identityConfigurationName)
 | |
|         {
 | |
|             if (identityConfigurationName == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("identityConfigurationName");
 | |
|             }
 | |
| 
 | |
|             SystemIdentityModelSection section = SystemIdentityModelSection.Current;
 | |
| 
 | |
|             if (section == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID7027));
 | |
|             }
 | |
| 
 | |
|             _identityConfigurationName = identityConfigurationName;
 | |
|             IdentityConfigurationElement element = section.IdentityConfigurationElements.GetElement(identityConfigurationName);
 | |
|             LoadConfiguration(element);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Initializes an instance of <see cref="IdentityConfiguration"/>
 | |
|         /// </summary>
 | |
|         /// <param name="identityConfigurationName">The name of the <service> element from which configuration is to be loaded.</param>
 | |
|         /// <exception cref="InvalidOperationException">Thrown if there is no <System.IdentityModel> configuration element</exception>
 | |
|         /// <param name="serviceCertificate">Thrown if there is no <System.IdentityModel> configuration element</param>
 | |
|         /// <remarks>If this constructor is called then a System.IdentityModel config section with the provided name must exist.</remarks>
 | |
|         public IdentityConfiguration(string identityConfigurationName, X509Certificate2 serviceCertificate)
 | |
|             : this(identityConfigurationName)
 | |
|         {
 | |
|             this.ServiceCertificate = serviceCertificate;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the AudienceRestriction.
 | |
|         /// </summary>
 | |
|         public AudienceRestriction AudienceRestriction
 | |
|         {
 | |
|             get { return _serviceHandlerConfiguration.AudienceRestriction; }
 | |
|             set { _serviceHandlerConfiguration.AudienceRestriction = value; }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the Caches configured.
 | |
|         /// </summary>
 | |
|         public IdentityModelCaches Caches
 | |
|         {
 | |
|             get { return _serviceHandlerConfiguration.Caches; }
 | |
|             set { _serviceHandlerConfiguration.Caches = value; }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the certificate validation mode used by handlers to validate issuer certificates
 | |
|         /// </summary>
 | |
|         public X509CertificateValidationMode CertificateValidationMode
 | |
|         {
 | |
|             get { return _serviceHandlerConfiguration.CertificateValidationMode; }
 | |
|             set { _serviceHandlerConfiguration.CertificateValidationMode = value; }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the certificate validator used by handlers to validate issuer certificates
 | |
|         /// </summary>
 | |
|         public X509CertificateValidator CertificateValidator
 | |
|         {
 | |
|             get { return _serviceHandlerConfiguration.CertificateValidator; }
 | |
|             set { _serviceHandlerConfiguration.CertificateValidator = value; }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or Sets the ClaimsAuthenticationManager.
 | |
|         /// </summary>
 | |
|         public ClaimsAuthenticationManager ClaimsAuthenticationManager
 | |
|         {
 | |
|             get { return _claimsAuthenticationManager; }
 | |
|             set
 | |
|             {
 | |
|                 if (value == null)
 | |
|                 {
 | |
|                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
 | |
|                 }
 | |
| 
 | |
|                 _claimsAuthenticationManager = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or Sets the ClaimsAuthorizationManager.
 | |
|         /// </summary>
 | |
|         public ClaimsAuthorizationManager ClaimsAuthorizationManager
 | |
|         {
 | |
|             get { return _claimsAuthorizationManager; }
 | |
|             set
 | |
|             {
 | |
|                 if (value == null)
 | |
|                 {
 | |
|                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
 | |
|                 }
 | |
| 
 | |
|                 _claimsAuthorizationManager = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or Sets detection of replaying of tokens by handlers in the default handler configuration.
 | |
|         /// </summary>
 | |
|         public bool DetectReplayedTokens
 | |
|         {
 | |
|             get { return _serviceHandlerConfiguration.DetectReplayedTokens; }
 | |
|             set { _serviceHandlerConfiguration.DetectReplayedTokens = value; }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Determines if <see cref="IdentityConfiguration.Initialize"/> has been called.
 | |
|         /// </summary>
 | |
|         public virtual bool IsInitialized
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _isInitialized;
 | |
|             }
 | |
|             protected set
 | |
|             {
 | |
|                 _isInitialized = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private static SecurityTokenResolver GetServiceTokenResolver(IdentityConfigurationElement element)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 return CustomTypeElement.Resolve<SecurityTokenResolver>(element.ServiceTokenResolver);
 | |
|             }
 | |
|             catch (ArgumentException inner)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ThrowHelperConfigurationError(
 | |
|                     element, ConfigurationStrings.ServiceTokenResolver, inner);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private static SecurityTokenResolver GetIssuerTokenResolver(IdentityConfigurationElement element)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 return CustomTypeElement.Resolve<SecurityTokenResolver>(element.IssuerTokenResolver);
 | |
|             }
 | |
|             catch (ArgumentException inner)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ThrowHelperConfigurationError(
 | |
|                     element, ConfigurationStrings.IssuerTokenResolver, inner);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private static ClaimsAuthenticationManager GetClaimsAuthenticationManager(IdentityConfigurationElement element)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 return CustomTypeElement.Resolve<ClaimsAuthenticationManager>(element.ClaimsAuthenticationManager);
 | |
|             }
 | |
|             catch (ArgumentException inner)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ThrowHelperConfigurationError(
 | |
|                     element, ConfigurationStrings.ClaimsAuthenticationManager, inner);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private static IssuerNameRegistry GetIssuerNameRegistry(IssuerNameRegistryElement element)
 | |
|         {
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 Type type = string.IsNullOrEmpty(element.Type) ? DefaultIssuerNameRegistryType : Type.GetType(element.Type);
 | |
|                 return TypeResolveHelper.Resolve<IssuerNameRegistry>(element, type);
 | |
|             }
 | |
|             catch (ArgumentException inner)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ThrowHelperConfigurationError(
 | |
|                     element, ConfigurationStrings.IssuerNameRegistry, inner);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Updates properties in the <see cref="SecurityTokenHandlerConfiguration"/> objects for the 
 | |
|         /// <see cref="SecurityTokenHandlerCollection"/> objects contained in 
 | |
|         /// <see cref="IdentityConfiguration.SecurityTokenHandlerCollectionManager"/> to be consistent with the property
 | |
|         /// values on this <see cref="IdentityConfiguration"/> instance.
 | |
|         /// </summary>
 | |
|         /// <remarks>
 | |
|         /// This method should be invoked prior to using these token handlers
 | |
|         /// for token processing.
 | |
|         /// </remarks>
 | |
|         /// <exception cref="InvalidOperationException">If this method is invoked more than once.</exception>
 | |
|         public virtual void Initialize()
 | |
|         {
 | |
|             if (this.IsInitialized)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID7009));
 | |
|             }
 | |
| 
 | |
|             SecurityTokenHandlerCollection defaultCollection = this.SecurityTokenHandlers;
 | |
| 
 | |
|             if (!object.ReferenceEquals(_serviceHandlerConfiguration, defaultCollection.Configuration))
 | |
|             {
 | |
|                 //
 | |
|                 // If someone has created their own new STHConfig and set it as default, leave that config alone.
 | |
|                 //
 | |
|                 TraceUtility.TraceString(TraceEventType.Information, SR.GetString(SR.ID4283));
 | |
|                 this.IsInitialized = true;
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             // Update the ServiceTokenResolver of the default TokenHandlerCollection's configuration, if serviceCertificate is set.
 | |
|             if (this.ServiceCertificate != null)
 | |
|             {
 | |
|                 SecurityTokenResolver serviceCertificateResolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(new ReadOnlyCollection<SecurityToken>(
 | |
|                                                       new SecurityToken[] { new X509SecurityToken(this.ServiceCertificate) }), false);
 | |
| 
 | |
|                 SecurityTokenResolver tokenResolver = this.SecurityTokenHandlers.Configuration.ServiceTokenResolver;
 | |
| 
 | |
|                 if ((tokenResolver != null) && (tokenResolver != EmptySecurityTokenResolver.Instance))
 | |
|                 {
 | |
|                     this.SecurityTokenHandlers.Configuration.ServiceTokenResolver = new AggregateTokenResolver(new SecurityTokenResolver[] { serviceCertificateResolver, tokenResolver });
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     this.SecurityTokenHandlers.Configuration.ServiceTokenResolver = serviceCertificateResolver;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             SecurityTokenResolver configuredIssuerTokenResolver = this.IssuerTokenResolver;
 | |
| 
 | |
|             if (this.IssuerTokenResolver == SecurityTokenHandlerConfiguration.DefaultIssuerTokenResolver)
 | |
|             {
 | |
|                 //
 | |
|                 // Add the known certificates from WCF's ServiceCredentials in front of 
 | |
|                 // the default issuer token resolver.
 | |
|                 //
 | |
|                 if (this.KnownIssuerCertificates != null)
 | |
|                 {
 | |
|                     int count = this.KnownIssuerCertificates.Count;
 | |
|                     if (count > 0)
 | |
|                     {
 | |
|                         SecurityToken[] tokens = new SecurityToken[count];
 | |
|                         for (int i = 0; i < count; i++)
 | |
|                         {
 | |
|                             tokens[i] = new X509SecurityToken(this.KnownIssuerCertificates[i]);
 | |
|                         }
 | |
| 
 | |
|                         SecurityTokenResolver knownCertificateTokenResolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(new ReadOnlyCollection<SecurityToken>(tokens), false);
 | |
|                         
 | |
|                         this.IssuerTokenResolver = new AggregateTokenResolver(new SecurityTokenResolver[] { knownCertificateTokenResolver, configuredIssuerTokenResolver });                       
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             
 | |
|             if (this.CertificateValidationMode != X509CertificateValidationMode.Custom)
 | |
|             {
 | |
|                 defaultCollection.Configuration.CertificateValidator = X509Util.CreateCertificateValidator(defaultCollection.Configuration.CertificateValidationMode,
 | |
|                                                                                                             defaultCollection.Configuration.RevocationMode,
 | |
|                                                                                                             defaultCollection.Configuration.TrustedStoreLocation);
 | |
|             }
 | |
|             else if (object.ReferenceEquals(defaultCollection.Configuration.CertificateValidator, SecurityTokenHandlerConfiguration.DefaultCertificateValidator))
 | |
|             {
 | |
|                 //
 | |
|                 // If the mode is custom but the validator or still default, something has gone wrong.
 | |
|                 //
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4280)));
 | |
|             }
 | |
| 
 | |
|             this.IsInitialized = true;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Loads the settings for the IdentityConfiguration from the application or web configuration file.
 | |
|         /// </summary>
 | |
|         /// <remarks>
 | |
|         /// If there is no configuration file, or the named section does not exist, then no exception is thrown,
 | |
|         /// instead the class is loaded with a set of default values.
 | |
|         /// </remarks>
 | |
|         protected void LoadConfiguration(IdentityConfigurationElement element)
 | |
|         {
 | |
| 
 | |
|             if (element != null)
 | |
|             {
 | |
|                 //
 | |
|                 // Load the claims authentication manager
 | |
|                 //
 | |
|                 if (element.ClaimsAuthenticationManager.IsConfigured)
 | |
|                 {
 | |
|                     _claimsAuthenticationManager = GetClaimsAuthenticationManager(element);
 | |
|                 }
 | |
| 
 | |
|                 //
 | |
|                 // Load the claims authorization manager.
 | |
|                 //
 | |
|                 if (element.ClaimsAuthorizationManager.IsConfigured)
 | |
|                 {
 | |
|                     _claimsAuthorizationManager = CustomTypeElement.Resolve<ClaimsAuthorizationManager>(element.ClaimsAuthorizationManager);
 | |
|                 }
 | |
| 
 | |
|                 //
 | |
|                 // Load the service level Security Token Handler configuration
 | |
|                 //
 | |
|                 _serviceHandlerConfiguration = LoadHandlerConfiguration(element);
 | |
|             }
 | |
| 
 | |
|             //
 | |
|             // Reads handler configuration via LoadConfiguredHandlers. Do this last.
 | |
|             //
 | |
|             _securityTokenHandlerCollectionManager = LoadHandlers(element);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Loads the <see cref="SecurityTokenHandlerCollectionManager"/> defined for a given service.
 | |
|         /// </summary>
 | |
|         /// <param name="serviceElement">The <see cref="IdentityConfigurationElement"/> used to configure this instance.</param>
 | |
|         /// <returns></returns>
 | |
|         protected SecurityTokenHandlerCollectionManager LoadHandlers(IdentityConfigurationElement serviceElement)
 | |
|         {
 | |
|             //
 | |
|             // We start with a token handler collection manager that contains a single collection that includes the default
 | |
|             // handlers for the system.
 | |
|             //
 | |
|             SecurityTokenHandlerCollectionManager manager = SecurityTokenHandlerCollectionManager.CreateEmptySecurityTokenHandlerCollectionManager();
 | |
| 
 | |
|             if (serviceElement != null)
 | |
|             {
 | |
|                 //
 | |
|                 // Load any token handler collections that appear as part of this service element
 | |
|                 //
 | |
|                 if (serviceElement.SecurityTokenHandlerSets.Count > 0)
 | |
|                 {
 | |
|                     foreach (SecurityTokenHandlerElementCollection handlerElementCollection in serviceElement.SecurityTokenHandlerSets)
 | |
|                     {
 | |
|                         try
 | |
|                         {
 | |
|                             SecurityTokenHandlerConfiguration handlerConfiguration;
 | |
|                             SecurityTokenHandlerCollection handlerCollection;
 | |
| 
 | |
|                             if (string.IsNullOrEmpty(handlerElementCollection.Name) ||
 | |
|                                  StringComparer.Ordinal.Equals(handlerElementCollection.Name, ConfigurationStrings.DefaultConfigurationElementName))
 | |
|                             {
 | |
|                                 //
 | |
|                                 // For the default collection, merge the IdentityConfiguration with the underlying config, if it exists.
 | |
|                                 //
 | |
|                                 if (handlerElementCollection.SecurityTokenHandlerConfiguration.IsConfigured)
 | |
|                                 {
 | |
|                                     //
 | |
|                                     // Configuration from a nested configuration object. We start with Service level configuration for 
 | |
|                                     // handlers and then override the collection specific configuration. The result is a new configuration
 | |
|                                     // object that can only be modified by accessing the collection or handlers configuration properties.
 | |
|                                     //
 | |
|                                     _serviceHandlerConfiguration = LoadHandlerConfiguration(serviceElement);
 | |
|                                     handlerConfiguration = LoadHandlerConfiguration(_serviceHandlerConfiguration, handlerElementCollection.SecurityTokenHandlerConfiguration);
 | |
|                                 }
 | |
|                                 else
 | |
|                                 {
 | |
|                                     //
 | |
|                                     // No nested configuration object. We use the values from the ServiceElement for this case.
 | |
|                                     //
 | |
|                                     handlerConfiguration = LoadHandlerConfiguration(serviceElement);
 | |
|                                 }
 | |
| 
 | |
|                                 _serviceHandlerConfiguration = handlerConfiguration;
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 //
 | |
|                                 // This is a non-default collection. There should be no settings inherited from IdentityConfiguration.
 | |
|                                 //
 | |
|                                 if (handlerElementCollection.SecurityTokenHandlerConfiguration.IsConfigured)
 | |
|                                 {
 | |
|                                     handlerConfiguration = LoadHandlerConfiguration(null, handlerElementCollection.SecurityTokenHandlerConfiguration);
 | |
|                                 }
 | |
|                                 else
 | |
|                                 {
 | |
|                                     //
 | |
|                                     // If there is no underlying config, set everything as default.
 | |
|                                     //
 | |
|                                     handlerConfiguration = new SecurityTokenHandlerConfiguration();
 | |
|                                 }
 | |
|                             }
 | |
| 
 | |
|                             handlerCollection = new SecurityTokenHandlerCollection(handlerConfiguration);
 | |
|                             manager[handlerElementCollection.Name] = handlerCollection;
 | |
| 
 | |
|                             foreach (CustomTypeElement handlerElement in handlerElementCollection)
 | |
|                             {
 | |
|                                 handlerCollection.Add(CustomTypeElement.Resolve<SecurityTokenHandler>(handlerElement));
 | |
|                             }
 | |
|                         }
 | |
|                         catch (ArgumentException inner)
 | |
|                         {
 | |
|                             throw DiagnosticUtility.ThrowHelperConfigurationError(serviceElement, handlerElementCollection.Name, inner);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 //
 | |
|                 // Ensure that the default usage collection always exists
 | |
|                 //
 | |
|                 if (!manager.ContainsKey(SecurityTokenHandlerCollectionManager.Usage.Default))
 | |
|                 {
 | |
|                     manager[SecurityTokenHandlerCollectionManager.Usage.Default] = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection(_serviceHandlerConfiguration);
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 //
 | |
|                 // Ensure that the default usage collection always exists
 | |
|                 //
 | |
|                 _serviceHandlerConfiguration = new SecurityTokenHandlerConfiguration();
 | |
| 
 | |
|                 _serviceHandlerConfiguration.MaxClockSkew = _serviceMaxClockSkew;
 | |
| 
 | |
|                 if (!manager.ContainsKey(SecurityTokenHandlerCollectionManager.Usage.Default))
 | |
|                 {
 | |
|                     manager[SecurityTokenHandlerCollectionManager.Usage.Default] = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection(_serviceHandlerConfiguration);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return manager;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Loads a SecurityTokenHandlerConfiguration using the elements directly under the ServiceElement.
 | |
|         /// </summary>
 | |
|         protected SecurityTokenHandlerConfiguration LoadHandlerConfiguration(IdentityConfigurationElement element)
 | |
|         {
 | |
| 
 | |
|             SecurityTokenHandlerConfiguration handlerConfiguration = new SecurityTokenHandlerConfiguration();
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 if (element.ElementInformation.Properties[ConfigurationStrings.MaximumClockSkew].ValueOrigin != PropertyValueOrigin.Default)
 | |
|                 {
 | |
|                     handlerConfiguration.MaxClockSkew = element.MaximumClockSkew;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     handlerConfiguration.MaxClockSkew = _serviceMaxClockSkew;
 | |
|                 }
 | |
|             }
 | |
|             catch (ArgumentException inner)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ThrowHelperConfigurationError(element, ConfigurationStrings.MaximumClockSkew, inner);
 | |
|             }
 | |
| 
 | |
|             if (element.AudienceUris.IsConfigured)
 | |
|             {
 | |
|                 handlerConfiguration.AudienceRestriction.AudienceMode = element.AudienceUris.Mode;
 | |
| 
 | |
|                 foreach (AudienceUriElement audienceUriElement in element.AudienceUris)
 | |
|                 {
 | |
|                     handlerConfiguration.AudienceRestriction.AllowedAudienceUris.Add(new Uri(audienceUriElement.Value, UriKind.RelativeOrAbsolute));
 | |
|                 }
 | |
|             }
 | |
|             if (element.Caches.IsConfigured)
 | |
|             {
 | |
|                 if (element.Caches.TokenReplayCache.IsConfigured)
 | |
|                 {
 | |
|                     handlerConfiguration.Caches.TokenReplayCache = CustomTypeElement.Resolve<TokenReplayCache>(element.Caches.TokenReplayCache);
 | |
|                 }
 | |
| 
 | |
|                 if (element.Caches.SessionSecurityTokenCache.IsConfigured)
 | |
|                 {
 | |
|                     handlerConfiguration.Caches.SessionSecurityTokenCache = CustomTypeElement.Resolve<SessionSecurityTokenCache>(element.Caches.SessionSecurityTokenCache);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (element.CertificateValidation.IsConfigured)
 | |
|             {
 | |
|                 handlerConfiguration.RevocationMode = element.CertificateValidation.RevocationMode;
 | |
|                 handlerConfiguration.CertificateValidationMode = element.CertificateValidation.CertificateValidationMode;
 | |
|                 handlerConfiguration.TrustedStoreLocation = element.CertificateValidation.TrustedStoreLocation;
 | |
| 
 | |
|                 if (element.CertificateValidation.CertificateValidator.IsConfigured)
 | |
|                 {
 | |
|                     handlerConfiguration.CertificateValidator = CustomTypeElement.Resolve<X509CertificateValidator>(element.CertificateValidation.CertificateValidator);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             //
 | |
|             // Load the issuer name registry
 | |
|             //
 | |
|             if (element.IssuerNameRegistry.IsConfigured)
 | |
|             {
 | |
|                 handlerConfiguration.IssuerNameRegistry = GetIssuerNameRegistry(element.IssuerNameRegistry);
 | |
|             }
 | |
| 
 | |
|             //
 | |
|             // Load the issuer token resolver
 | |
|             //
 | |
|             if (element.IssuerTokenResolver.IsConfigured)
 | |
|             {
 | |
|                 handlerConfiguration.IssuerTokenResolver = GetIssuerTokenResolver(element);
 | |
|             }
 | |
| 
 | |
|             //
 | |
|             // SaveBootstrapContext
 | |
|             //
 | |
|             handlerConfiguration.SaveBootstrapContext = element.SaveBootstrapContext;
 | |
| 
 | |
|             //
 | |
|             // Load the service token resolver
 | |
|             //
 | |
|             if (element.ServiceTokenResolver.IsConfigured)
 | |
|             {
 | |
|                 handlerConfiguration.ServiceTokenResolver = GetServiceTokenResolver(element);
 | |
|             }
 | |
| 
 | |
|             //
 | |
|             // TokenReplayCache related items
 | |
|             //
 | |
|             if (element.TokenReplayDetection.IsConfigured)
 | |
|             {
 | |
|                 //
 | |
|                 // Set on SecurityTokenHandlerConfiguration
 | |
|                 //
 | |
| 
 | |
|                 // DetectReplayedTokens set - { true | false }
 | |
|                 //
 | |
|                 handlerConfiguration.DetectReplayedTokens = element.TokenReplayDetection.Enabled;
 | |
| 
 | |
|                 // ExpirationPeriod { TimeSpan }
 | |
|                 //
 | |
|                 handlerConfiguration.TokenReplayCacheExpirationPeriod = element.TokenReplayDetection.ExpirationPeriod;
 | |
|             }
 | |
| 
 | |
|             return handlerConfiguration;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Loads configuration elements pertaining to the <see cref="SecurityTokenHandlerCollection"/>
 | |
|         /// </summary>
 | |
|         /// <param name="baseConfiguration">Base <see cref="SecurityTokenHandlerConfiguration"/> from which to inherit default values.</param>
 | |
|         /// <param name="element">The <see cref="SecurityTokenHandlerConfigurationElement"/> from the configuration file.</param>
 | |
|         /// <returns></returns>
 | |
|         protected SecurityTokenHandlerConfiguration LoadHandlerConfiguration(SecurityTokenHandlerConfiguration baseConfiguration, SecurityTokenHandlerConfigurationElement element)
 | |
|         {
 | |
|             SecurityTokenHandlerConfiguration handlerConfiguration = (baseConfiguration == null) ? new SecurityTokenHandlerConfiguration() : baseConfiguration;
 | |
| 
 | |
|             if (element.AudienceUris.IsConfigured)
 | |
|             {
 | |
|                 //
 | |
|                 // There is no inheritance of the content of the element from base to child, only the whole element. If the
 | |
|                 // user specifies any part, they must specify it all.
 | |
|                 //
 | |
|                 handlerConfiguration.AudienceRestriction.AudienceMode = AudienceUriMode.Always;
 | |
|                 handlerConfiguration.AudienceRestriction.AllowedAudienceUris.Clear();
 | |
| 
 | |
|                 handlerConfiguration.AudienceRestriction.AudienceMode = element.AudienceUris.Mode;
 | |
| 
 | |
|                 foreach (AudienceUriElement audienceUriElement in element.AudienceUris)
 | |
|                 {
 | |
|                     handlerConfiguration.AudienceRestriction.AllowedAudienceUris.Add(new Uri(audienceUriElement.Value, UriKind.RelativeOrAbsolute));
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (element.Caches.IsConfigured)
 | |
|             {
 | |
|                 if (element.Caches.TokenReplayCache.IsConfigured)
 | |
|                 {
 | |
|                     handlerConfiguration.Caches.TokenReplayCache = CustomTypeElement.Resolve<TokenReplayCache>(element.Caches.TokenReplayCache);
 | |
|                 }
 | |
| 
 | |
|                 if (element.Caches.SessionSecurityTokenCache.IsConfigured)
 | |
|                 {
 | |
|                     handlerConfiguration.Caches.SessionSecurityTokenCache = CustomTypeElement.Resolve<SessionSecurityTokenCache>(element.Caches.SessionSecurityTokenCache);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (element.CertificateValidation.IsConfigured)
 | |
|             {
 | |
|                 handlerConfiguration.RevocationMode = element.CertificateValidation.RevocationMode;
 | |
|                 handlerConfiguration.CertificateValidationMode = element.CertificateValidation.CertificateValidationMode;
 | |
|                 handlerConfiguration.TrustedStoreLocation = element.CertificateValidation.TrustedStoreLocation;
 | |
| 
 | |
|                 if (element.CertificateValidation.CertificateValidator.IsConfigured)
 | |
|                 {
 | |
|                     handlerConfiguration.CertificateValidator = CustomTypeElement.Resolve<X509CertificateValidator>(element.CertificateValidation.CertificateValidator);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             //
 | |
|             // Load the issuer name registry
 | |
|             //
 | |
|             if (element.IssuerNameRegistry.IsConfigured)
 | |
|             {
 | |
|                 handlerConfiguration.IssuerNameRegistry = GetIssuerNameRegistry(element.IssuerNameRegistry);
 | |
|             }
 | |
| 
 | |
|             //
 | |
|             // Load the issuer token resolver
 | |
|             //
 | |
|             if (element.IssuerTokenResolver.IsConfigured)
 | |
|             {
 | |
|                 handlerConfiguration.IssuerTokenResolver = CustomTypeElement.Resolve<SecurityTokenResolver>(element.IssuerTokenResolver);
 | |
|             }
 | |
| 
 | |
|             //
 | |
|             // Load MaxClockSkew
 | |
|             //
 | |
|             try
 | |
|             {
 | |
|                 if (element.ElementInformation.Properties[ConfigurationStrings.MaximumClockSkew].ValueOrigin != PropertyValueOrigin.Default)
 | |
|                 {
 | |
|                     handlerConfiguration.MaxClockSkew = element.MaximumClockSkew;
 | |
|                 }
 | |
|             }
 | |
|             catch (ArgumentException inner)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ThrowHelperConfigurationError(element, ConfigurationStrings.MaximumClockSkew, inner);
 | |
|             }
 | |
| 
 | |
|             //
 | |
|             // SaveBootstrapTokens
 | |
|             //
 | |
|             if (element.ElementInformation.Properties[ConfigurationStrings.SaveBootstrapContext].ValueOrigin != PropertyValueOrigin.Default)
 | |
|             {
 | |
|                 handlerConfiguration.SaveBootstrapContext = element.SaveBootstrapContext;
 | |
|             }
 | |
| 
 | |
|             //
 | |
|             // Load the service token resolver
 | |
|             //
 | |
|             if (element.ServiceTokenResolver.IsConfigured)
 | |
|             {
 | |
|                 handlerConfiguration.ServiceTokenResolver = CustomTypeElement.Resolve<SecurityTokenResolver>(element.ServiceTokenResolver);
 | |
|             }
 | |
| 
 | |
|             //
 | |
|             // TokenReplayCache related items
 | |
|             //
 | |
|             if (element.TokenReplayDetection.IsConfigured)
 | |
|             {
 | |
|                 //
 | |
|                 // Set on SecurityTokenHandlerConfiguration
 | |
|                 //
 | |
| 
 | |
|                 //
 | |
|                 // DetectReplayedTokens set - { true | false }
 | |
|                 //
 | |
|                 handlerConfiguration.DetectReplayedTokens = element.TokenReplayDetection.Enabled;
 | |
| 
 | |
|                 //
 | |
|                 // ExpirationPeriod { TimeSpan }
 | |
|                 //
 | |
|                 handlerConfiguration.TokenReplayCacheExpirationPeriod = element.TokenReplayDetection.ExpirationPeriod;
 | |
| 
 | |
|             }
 | |
| 
 | |
|             return handlerConfiguration;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the maximum allowable time difference between the 
 | |
|         /// system clocks of the two parties that are communicating.
 | |
|         /// </summary>
 | |
|         public TimeSpan MaxClockSkew
 | |
|         {
 | |
|             get { return _serviceHandlerConfiguration.MaxClockSkew; }
 | |
|             set { _serviceHandlerConfiguration.MaxClockSkew = value; }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the service name of this configuration.
 | |
|         /// </summary>
 | |
|         public string Name
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _identityConfigurationName;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the IssuerNameRegistry used to resolve issuer names.
 | |
|         /// </summary>
 | |
|         public IssuerNameRegistry IssuerNameRegistry
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _serviceHandlerConfiguration.IssuerNameRegistry;
 | |
|             }
 | |
|             set
 | |
|             {
 | |
|                 if (value == null)
 | |
|                 {
 | |
|                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
 | |
|                 }
 | |
| 
 | |
|                 _serviceHandlerConfiguration.IssuerNameRegistry = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// The service certificate to initialize the ServiceTokenResolver and the SessionSecurityTokenHandler.
 | |
|         /// </summary>
 | |
|         public X509Certificate2 ServiceCertificate
 | |
|         {
 | |
|             get { return _serviceCertificate; }
 | |
|             set { this._serviceCertificate = value; }
 | |
|         }
 | |
| 
 | |
|         internal List<X509Certificate2> KnownIssuerCertificates
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return this.knownCertificates;
 | |
|             }
 | |
|             set
 | |
|             {
 | |
|                 this.knownCertificates = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or Sets the Issuer token resolver.
 | |
|         /// </summary>
 | |
|         public SecurityTokenResolver IssuerTokenResolver
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _serviceHandlerConfiguration.IssuerTokenResolver;
 | |
|             }
 | |
|             set
 | |
|             {
 | |
|                 if (value == null)
 | |
|                 {
 | |
|                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
 | |
|                 }
 | |
| 
 | |
|                 _serviceHandlerConfiguration.IssuerTokenResolver = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the revocation mode used by handlers to validate issuer certificates
 | |
|         /// </summary>
 | |
|         public X509RevocationMode RevocationMode
 | |
|         {
 | |
|             get { return _serviceHandlerConfiguration.RevocationMode; }
 | |
|             set { _serviceHandlerConfiguration.RevocationMode = value; }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or Sets the Service token resolver.
 | |
|         /// </summary>
 | |
|         public SecurityTokenResolver ServiceTokenResolver
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _serviceHandlerConfiguration.ServiceTokenResolver;
 | |
|             }
 | |
|             set
 | |
|             {
 | |
|                 if (value == null)
 | |
|                 {
 | |
|                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
 | |
|                 }
 | |
| 
 | |
|                 _serviceHandlerConfiguration.ServiceTokenResolver = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets if BootstrapContext is saved in the ClaimsIdentity and Sessions after token validation.
 | |
|         /// </summary>
 | |
|         public bool SaveBootstrapContext
 | |
|         {
 | |
|             get { return _serviceHandlerConfiguration.SaveBootstrapContext; }
 | |
|             set { _serviceHandlerConfiguration.SaveBootstrapContext = value; }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// The <see cref="SecurityTokenHandlerCollectionManager" /> containing the set of <see cref="SecurityTokenHandler" />
 | |
|         /// objects used for serializing and validating tokens found in WS-Trust messages.
 | |
|         /// </summary>
 | |
|         public SecurityTokenHandlerCollectionManager SecurityTokenHandlerCollectionManager
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _securityTokenHandlerCollectionManager;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// The <see cref="SecurityTokenHandlerCollection" /> collection of <see cref="SecurityTokenHandler" />
 | |
|         /// objects used for serializing and validating tokens found in WS-Trust messages.
 | |
|         /// If user wants to register their own token handler, they
 | |
|         /// can simply add their own handler to this collection.
 | |
|         /// </summary>
 | |
|         public SecurityTokenHandlerCollection SecurityTokenHandlers
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _securityTokenHandlerCollectionManager[SecurityTokenHandlerCollectionManager.Usage.Default];
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or Sets the expiration period for items placed in the TokenReplayCache.
 | |
|         /// </summary>
 | |
|         public TimeSpan TokenReplayCacheExpirationPeriod
 | |
|         {
 | |
|             get { return _serviceHandlerConfiguration.TokenReplayCacheExpirationPeriod; }
 | |
|             set { _serviceHandlerConfiguration.TokenReplayCacheExpirationPeriod = value; }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the trusted store location used by handlers to validate issuer certificates
 | |
|         /// </summary>
 | |
|         public StoreLocation TrustedStoreLocation
 | |
|         {
 | |
|             get { return _serviceHandlerConfiguration.TrustedStoreLocation; }
 | |
|             set { _serviceHandlerConfiguration.TrustedStoreLocation = value; }
 | |
|         }
 | |
|     }
 | |
| }
 |