You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			724 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			724 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //-----------------------------------------------------------------------
 | |
| // <copyright file="SecurityTokenHandlerCollection.cs" company="Microsoft">
 | |
| //     Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| // </copyright>
 | |
| //-----------------------------------------------------------------------
 | |
| 
 | |
| namespace System.IdentityModel.Tokens
 | |
| {
 | |
|     using System.Collections.Generic;
 | |
|     using System.Collections.ObjectModel;
 | |
|     using System.IdentityModel.Selectors;
 | |
|     using System.Security.Claims;
 | |
|     using System.Xml;
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Defines a collection of SecurityTokenHandlers.
 | |
|     /// </summary>
 | |
|     public class SecurityTokenHandlerCollection : Collection<SecurityTokenHandler>
 | |
|     {
 | |
|         internal static int defaultHandlerCollectionCount = 8;
 | |
| 
 | |
|         private Dictionary<string, SecurityTokenHandler> handlersByIdentifier = new Dictionary<string, SecurityTokenHandler>();
 | |
|         private Dictionary<Type, SecurityTokenHandler> handlersByType = new Dictionary<Type, SecurityTokenHandler>();
 | |
| 
 | |
|         private SecurityTokenHandlerConfiguration configuration;
 | |
| 
 | |
|         private KeyInfoSerializer keyInfoSerializer;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates an instance of <see cref="SecurityTokenHandlerCollection"/>.
 | |
|         /// Creates an empty set.
 | |
|         /// </summary>
 | |
|         public SecurityTokenHandlerCollection()
 | |
|             : this(new SecurityTokenHandlerConfiguration())
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates an instance of <see cref="SecurityTokenHandlerCollection"/>.
 | |
|         /// Creates an empty set.
 | |
|         /// </summary>
 | |
|         /// <param name="configuration">The configuration to associate with the collection.</param>
 | |
|         public SecurityTokenHandlerCollection(SecurityTokenHandlerConfiguration configuration)
 | |
|         {
 | |
|             if (configuration == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("configuration");
 | |
|             }
 | |
| 
 | |
|             this.configuration = configuration;
 | |
|             this.keyInfoSerializer = new KeyInfoSerializer(true);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates an instance of <see cref="SecurityTokenHandlerCollection"/>
 | |
|         /// </summary>
 | |
|         /// <param name="handlers">List of SecurityTokenHandlers to initialize from.</param>
 | |
|         /// <remarks>
 | |
|         /// Do not use this constructor to attempt to clone an instance of a SecurityTokenHandlerCollection,
 | |
|         /// use the Clone method instead.
 | |
|         /// </remarks>
 | |
|         public SecurityTokenHandlerCollection(IEnumerable<SecurityTokenHandler> handlers)
 | |
|             : this(handlers, new SecurityTokenHandlerConfiguration())
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates an instance of <see cref="SecurityTokenHandlerCollection"/>
 | |
|         /// </summary>
 | |
|         /// <param name="handlers">List of SecurityTokenHandlers to initialize from.</param>
 | |
|         /// <param name="configuration">The <see cref="SecurityTokenHandlerConfiguration"/> in effect.</param>
 | |
|         /// <remarks>
 | |
|         /// Do not use this constructor to attempt to clone an instance of a SecurityTokenHandlerCollection,
 | |
|         /// use the Clone method instead.
 | |
|         /// </remarks>
 | |
|         public SecurityTokenHandlerCollection(IEnumerable<SecurityTokenHandler> handlers, SecurityTokenHandlerConfiguration configuration)
 | |
|             : this(configuration)
 | |
|         {
 | |
|             if (handlers == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("handlers");
 | |
|             }
 | |
| 
 | |
|             foreach (SecurityTokenHandler handler in handlers)
 | |
|             {
 | |
|                 Add(handler);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets an instance of <see cref="SecurityTokenHandlerConfiguration"/>
 | |
|         /// </summary>
 | |
|         public SecurityTokenHandlerConfiguration Configuration
 | |
|         {
 | |
|             get { return this.configuration; }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the List of System.Type of the Token Handlers in this collection.
 | |
|         /// </summary>
 | |
|         public IEnumerable<Type> TokenTypes
 | |
|         {
 | |
|             get { return this.handlersByType.Keys; }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the list of Token type Identifier of the Token Handlers.
 | |
|         /// </summary>
 | |
|         public IEnumerable<string> TokenTypeIdentifiers
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return this.handlersByIdentifier.Keys;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets a Token Handler by its Token Type Identifier.
 | |
|         /// </summary>
 | |
|         /// <param name="tokenTypeIdentifier">The Token Type Identfier string to search for.</param>
 | |
|         /// <returns>Instance of a SecurityTokenHandler.</returns>
 | |
|         public SecurityTokenHandler this[string tokenTypeIdentifier]
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (string.IsNullOrEmpty(tokenTypeIdentifier))
 | |
|                 {
 | |
|                     return null;
 | |
|                 }
 | |
| 
 | |
|                 SecurityTokenHandler handler;
 | |
|                 this.handlersByIdentifier.TryGetValue(tokenTypeIdentifier, out handler);
 | |
|                 return handler;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets a Token Handler that can handle a given SecurityToken.
 | |
|         /// </summary>
 | |
|         /// <param name="token">SecurityToken for which a Token Handler is requested.</param>
 | |
|         /// <returns>Instance of SecurityTokenHandler.</returns>
 | |
|         public SecurityTokenHandler this[SecurityToken token]
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (null == token)
 | |
|                 {
 | |
|                     return null;
 | |
|                 }
 | |
| 
 | |
|                 return this[token.GetType()];
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets a Token Handler based on the System.Type of the token.
 | |
|         /// </summary>
 | |
|         /// <param name="tokenType">System.Type of the Token that needs to be handled.</param>
 | |
|         /// <returns>Instance of SecurityTokenHandler.</returns>
 | |
|         public SecurityTokenHandler this[Type tokenType]
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 SecurityTokenHandler handler = null;
 | |
|                 if (tokenType != null)
 | |
|                 {
 | |
|                     this.handlersByType.TryGetValue(tokenType, out handler);
 | |
|                 }
 | |
| 
 | |
|                 return handler;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates a system default collection of basic SecurityTokenHandlers, each of which has the system default configuration.
 | |
|         /// The SecurityTokenHandlers in this collection must be configured with service specific data before they can be used.
 | |
|         /// </summary>
 | |
|         /// <returns>A SecurityTokenHandlerCollection with default basic SecurityTokenHandlers.</returns>
 | |
|         public static SecurityTokenHandlerCollection CreateDefaultSecurityTokenHandlerCollection()
 | |
|         {
 | |
|             return CreateDefaultSecurityTokenHandlerCollection(new SecurityTokenHandlerConfiguration());
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates a system default collection of basic SecurityTokenHandlers, each of which has the system default configuration.
 | |
|         /// The SecurityTokenHandlers in this collection must be configured with service specific data before they can be used.
 | |
|         /// </summary>
 | |
|         /// <param name="configuration">The configuration to associate with the collection.</param>
 | |
|         /// <returns>A SecurityTokenHandlerCollection with default basic SecurityTokenHandlers.</returns>
 | |
|         public static SecurityTokenHandlerCollection CreateDefaultSecurityTokenHandlerCollection(SecurityTokenHandlerConfiguration configuration)
 | |
|         {
 | |
| 
 | |
|             SecurityTokenHandlerCollection collection = new SecurityTokenHandlerCollection(new SecurityTokenHandler[] {
 | |
|                                                                                                  new KerberosSecurityTokenHandler(),
 | |
|                                                                                                  new RsaSecurityTokenHandler(),
 | |
|                                                                                                  new SamlSecurityTokenHandler(), 
 | |
|                                                                                                  new Saml2SecurityTokenHandler(),
 | |
|                                                                                                  new WindowsUserNameSecurityTokenHandler(),
 | |
|                                                                                                  new X509SecurityTokenHandler(),
 | |
|                                                                                                  new EncryptedSecurityTokenHandler(),
 | |
|                                                                                                  new SessionSecurityTokenHandler(),
 | |
|                                                                                                 },
 | |
|                                                                                              configuration);
 | |
| 
 | |
|             defaultHandlerCollectionCount = collection.Count;
 | |
| 
 | |
|             return collection;
 | |
|         }
 | |
| 
 | |
|         internal SecurityTokenSerializer KeyInfoSerializer
 | |
|         {
 | |
|             get { return this.keyInfoSerializer; }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Adds a new handler or replace the existing handler with the same token type identifier 
 | |
|         /// with with the new handler.
 | |
|         /// </summary>
 | |
|         /// <param name="handler">The SecurityTokenHandler to add or replace</param>
 | |
|         /// <exception cref="ArgumentNullException">When the input parameter is null.</exception>
 | |
|         public void AddOrReplace(SecurityTokenHandler handler)
 | |
|         {
 | |
|             if (handler == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("handler");
 | |
|             }
 | |
| 
 | |
|             // Remove the old one if it exists
 | |
|             Type tokenType = handler.TokenType;
 | |
|             if (tokenType != null && this.handlersByType.ContainsKey(tokenType))
 | |
|             {
 | |
|                 Remove(this[tokenType]);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 string[] identifiers = handler.GetTokenTypeIdentifiers();
 | |
|                 if (identifiers != null)
 | |
|                 {
 | |
|                     foreach (string tokenTypeIdentifier in identifiers)
 | |
|                     {
 | |
|                         if (tokenTypeIdentifier != null && this.handlersByIdentifier.ContainsKey(tokenTypeIdentifier))
 | |
|                         {
 | |
|                             Remove(this[tokenTypeIdentifier]);
 | |
|                             break;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // Add the new handler in the collection
 | |
|             Add(handler);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Checks if a token can be read using the SecurityTokenHandlers.
 | |
|         /// </summary>
 | |
|         /// <param name="reader">XmlReader pointing at token.</param>
 | |
|         /// <returns>True if the token can be read, false otherwise</returns>
 | |
|         /// <exception cref="ArgumentNullException">The input argument 'reader' is null.</exception>
 | |
|         public bool CanReadToken(XmlReader reader)
 | |
|         {
 | |
|             if (reader == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
 | |
|             }
 | |
| 
 | |
|             foreach (SecurityTokenHandler handler in this)
 | |
|             {
 | |
|                 if (null != handler && handler.CanReadToken(reader))
 | |
|                 {
 | |
|                     return true;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Checks if a token can be read using the SecurityTokenHandlers.
 | |
|         /// </summary>
 | |
|         /// <param name="tokenString">The token string thats needs to be read.</param>
 | |
|         /// <returns>True if the token can be read, false otherwise</returns>
 | |
|         /// <exception cref="ArgumentException">The input argument 'tokenString' is null or empty.</exception>
 | |
|         public bool CanReadToken(string tokenString)
 | |
|         {
 | |
|             if (String.IsNullOrEmpty(tokenString))
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNullOrEmptyString("tokenString");
 | |
|             }
 | |
| 
 | |
|             foreach (SecurityTokenHandler handler in this)
 | |
|             {
 | |
|                 if (null != handler && handler.CanReadToken(tokenString))
 | |
|                 {
 | |
|                     return true;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return false;
 | |
|         }
 | |
|         
 | |
|         /// <summary>
 | |
|         /// Checks if a token can be written using the SecurityTokenHandlers.
 | |
|         /// </summary>
 | |
|         /// <param name="token">SecurityToken to be written out.</param>
 | |
|         /// <returns>True if the token can be written, false otherwise</returns>
 | |
|         /// <exception cref="ArgumentNullException">The input argument 'token' is null.</exception>
 | |
|         public bool CanWriteToken(SecurityToken token)
 | |
|         {
 | |
|             if (token == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
 | |
|             }
 | |
| 
 | |
|             SecurityTokenHandler handler = this[token];
 | |
|             if (null != handler && handler.CanWriteToken)
 | |
|             {
 | |
|                 return true;
 | |
|             }
 | |
| 
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates a SecurityToken from the given SecurityTokenDescriptor using the list of
 | |
|         /// SecurityTokenHandlers.
 | |
|         /// </summary>
 | |
|         /// <param name="tokenDescriptor">SecurityTokenDescriptor for the token to be created.</param>
 | |
|         /// <returns>Instance of <see cref="SecurityToken"/></returns>
 | |
|         /// <exception cref="ArgumentNullException">The input argument 'tokenDescriptor' is null.</exception>
 | |
|         public SecurityToken CreateToken(SecurityTokenDescriptor tokenDescriptor)
 | |
|         {
 | |
|             if (tokenDescriptor == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenDescriptor");
 | |
|             }
 | |
| 
 | |
|             SecurityTokenHandler handler = this[tokenDescriptor.TokenType];
 | |
|             if (null == handler)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4020, tokenDescriptor.TokenType)));
 | |
|             }
 | |
| 
 | |
|             return handler.CreateToken(tokenDescriptor);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Validates a given token using the SecurityTokenHandlers.
 | |
|         /// </summary>
 | |
|         /// <param name="token">The SecurityToken to be validated.</param>
 | |
|         /// <returns>A <see cref="ReadOnlyCollection{T}"/> of <see cref="ClaimsIdentity"/> representing the identities contained in the token.</returns>
 | |
|         /// <exception cref="ArgumentNullException">The input argument 'token' is null.</exception>
 | |
|         /// <exception cref="InvalidOperationException">A <see cref="SecurityTokenHandler"/> cannot be found that can validate the <see cref="SecurityToken"/>.</exception>                
 | |
|         public ReadOnlyCollection<ClaimsIdentity> ValidateToken(SecurityToken token)
 | |
|         {
 | |
|             if (token == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
 | |
|             }
 | |
| 
 | |
|             SecurityTokenHandler handler = this[token];
 | |
|             if (null == handler || !handler.CanValidateToken)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4011, token.GetType())));
 | |
|             }
 | |
| 
 | |
|             return handler.ValidateToken(token);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Reads a token using the TokenHandlers.
 | |
|         /// </summary>
 | |
|         /// <param name="reader">XmlReader pointing at token.</param>
 | |
|         /// <returns>Instance of <see cref="SecurityToken"/></returns>
 | |
|         /// <exception cref="ArgumentNullException">The input argument 'reader' is null.</exception>
 | |
|         public SecurityToken ReadToken(XmlReader reader)
 | |
|         {
 | |
|             if (reader == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
 | |
|             }
 | |
| 
 | |
|             foreach (SecurityTokenHandler handler in this)
 | |
|             {
 | |
|                 if (null != handler && handler.CanReadToken(reader))
 | |
|                 {
 | |
|                     return handler.ReadToken(reader);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return null;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Reads a token using the TokenHandlers.
 | |
|         /// </summary>
 | |
|         /// <param name="tokenString">The token string to be deserialized.</param>
 | |
|         /// <returns>Instance of <see cref="SecurityToken"/></returns>
 | |
|         /// <exception cref="ArgumentException">The input argument 'tokenString' is null or empty.</exception>
 | |
|         public SecurityToken ReadToken(string tokenString)
 | |
|         {
 | |
|             if (String.IsNullOrEmpty(tokenString))
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNullOrEmptyString("tokenString");
 | |
|             }
 | |
| 
 | |
|             foreach (SecurityTokenHandler handler in this)
 | |
|             {
 | |
|                 if (null != handler && handler.CanReadToken(tokenString))
 | |
|                 {
 | |
|                     return handler.ReadToken(tokenString);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return null;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Writes a given SecurityToken to the XmlWriter.
 | |
|         /// </summary>
 | |
|         /// <param name="writer">XmlWriter to write the token into.</param>
 | |
|         /// <param name="token">SecurityToken to be written out.</param>
 | |
|         /// <exception cref="ArgumentNullException">The input argument 'writer' or 'token' is null.</exception>
 | |
|         public void WriteToken(XmlWriter writer, SecurityToken token)
 | |
|         {
 | |
|             if (writer == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
 | |
|             }
 | |
| 
 | |
|             if (token == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
 | |
|             }
 | |
| 
 | |
|             SecurityTokenHandler handler = this[token];
 | |
|             if (null == handler || !handler.CanWriteToken)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4010, token.GetType())));
 | |
|             }
 | |
| 
 | |
|             handler.WriteToken(writer, token);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Writes a given SecurityToken to a string.
 | |
|         /// </summary>
 | |
|         /// <param name="token">SecurityToken to be written out.</param>
 | |
|         /// <returns>The serialized token.</returns>
 | |
|         /// <exception cref="ArgumentNullException">The input argument 'token' is null.</exception>
 | |
|         public string WriteToken(SecurityToken token)
 | |
|         {
 | |
|             if (token == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
 | |
|             }
 | |
| 
 | |
|             SecurityTokenHandler handler = this[token];
 | |
|             if (null == handler || !handler.CanWriteToken)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4010, token.GetType())));
 | |
|             }
 | |
| 
 | |
|             return handler.WriteToken(token);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Override. (Inherited from Collection<T>"/>
 | |
|         /// </summary>
 | |
|         protected override void ClearItems()
 | |
|         {
 | |
|             base.ClearItems();
 | |
|             this.handlersByIdentifier.Clear();
 | |
|             this.handlersByType.Clear();
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Override. (Inherited from Collection<T>"/>
 | |
|         /// </summary>
 | |
|         /// <param name="index">The zero-based index at which item should be inserted.</param>
 | |
|         /// <param name="item">The object to insert. The value can be null for reference types.</param>
 | |
|         protected override void InsertItem(int index, SecurityTokenHandler item)
 | |
|         {
 | |
|             base.InsertItem(index, item);
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 this.AddToDictionaries(item);
 | |
|             }
 | |
|             catch
 | |
|             {
 | |
|                 base.RemoveItem(index);
 | |
|                 throw;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Override. (Inherited from Collection<T>"/>
 | |
|         /// </summary>
 | |
|         /// <param name="index">The zero-based index of the element to remove.</param>
 | |
|         protected override void RemoveItem(int index)
 | |
|         {
 | |
|             SecurityTokenHandler removedItem = Items[index];
 | |
|             base.RemoveItem(index);
 | |
|             this.RemoveFromDictionaries(removedItem);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Override. (Inherited from Collection<T>"/>
 | |
|         /// </summary>
 | |
|         /// <param name="index">The zero-based index of the element to replace.</param>
 | |
|         /// <param name="item">The new value for the element at the specified index. The value can be null for reference types.</param>
 | |
|         protected override void SetItem(int index, SecurityTokenHandler item)
 | |
|         {
 | |
|             SecurityTokenHandler replaced = Items[index];
 | |
|             base.SetItem(index, item);
 | |
| 
 | |
|             this.RemoveFromDictionaries(replaced);
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 this.AddToDictionaries(item);
 | |
|             }
 | |
|             catch
 | |
|             {
 | |
|                 base.SetItem(index, replaced);
 | |
|                 this.AddToDictionaries(replaced);
 | |
|                 throw;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public bool CanReadKeyIdentifierClause(XmlReader reader)
 | |
|         {
 | |
|             if (reader == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
 | |
|             }
 | |
| 
 | |
|             return CanReadKeyIdentifierClauseCore(reader);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Checks if the wrapped SecurityTokenHandler or the base WSSecurityTokenSerializer can read the 
 | |
|         /// SecurityKeyIdentifierClause.
 | |
|         /// </summary>
 | |
|         /// <param name="reader">Reader to a SecurityKeyIdentifierClause.</param>
 | |
|         /// <returns>'True' if the SecurityKeyIdentifierCause can be read.</returns>
 | |
|         /// <exception cref="ArgumentNullException">The input parameter 'reader' is null.</exception>
 | |
|         protected virtual bool CanReadKeyIdentifierClauseCore(XmlReader reader)
 | |
|         {
 | |
|             if (reader == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
 | |
|             }
 | |
| 
 | |
|             foreach (SecurityTokenHandler securityTokenHandler in this)
 | |
|             {
 | |
|                 if (securityTokenHandler.CanReadKeyIdentifierClause(reader))
 | |
|                 {
 | |
|                     return true;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         public SecurityKeyIdentifierClause ReadKeyIdentifierClause(XmlReader reader)
 | |
|         {
 | |
|             if (reader == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
 | |
|             }
 | |
| 
 | |
|             return ReadKeyIdentifierClauseCore(reader);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Deserializes a SecurityKeyIdentifierClause from the given reader.
 | |
|         /// </summary>
 | |
|         /// <param name="reader">XmlReader to a SecurityKeyIdentifierClause.</param>
 | |
|         /// <returns>The deserialized SecurityKeyIdentifierClause.</returns>
 | |
|         /// <exception cref="ArgumentNullException">The input parameter 'reader' is null.</exception>
 | |
|         protected virtual SecurityKeyIdentifierClause ReadKeyIdentifierClauseCore(XmlReader reader)
 | |
|         {
 | |
|             if (reader == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
 | |
|             }
 | |
| 
 | |
|             foreach (SecurityTokenHandler securityTokenHandler in this)
 | |
|             {
 | |
|                 if (securityTokenHandler.CanReadKeyIdentifierClause(reader))
 | |
|                 {
 | |
|                     return securityTokenHandler.ReadKeyIdentifierClause(reader);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return this.keyInfoSerializer.ReadKeyIdentifierClause(reader);
 | |
|         }
 | |
| 
 | |
|         public void WriteKeyIdentifierClause(XmlWriter writer, SecurityKeyIdentifierClause keyIdentifierClause)
 | |
|         {
 | |
|             if (writer == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
 | |
|             }
 | |
| 
 | |
|             if (keyIdentifierClause == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
 | |
|             }
 | |
| 
 | |
|             WriteKeyIdentifierClauseCore(writer, keyIdentifierClause);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Serializes the given SecurityKeyIdentifierClause in a XmlWriter.
 | |
|         /// </summary>
 | |
|         /// <param name="writer">XmlWriter to write into.</param>
 | |
|         /// <param name="keyIdentifierClause">SecurityKeyIdentifierClause to be written.</param>
 | |
|         /// <exception cref="ArgumentNullException">The input parameter 'writer' or 'keyIdentifierClause' is null.</exception>
 | |
|         protected virtual void WriteKeyIdentifierClauseCore(XmlWriter writer, SecurityKeyIdentifierClause keyIdentifierClause)
 | |
|         {
 | |
|             if (writer == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
 | |
|             }
 | |
| 
 | |
|             if (keyIdentifierClause == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
 | |
|             }
 | |
| 
 | |
|             foreach (SecurityTokenHandler securityTokenHandler in this)
 | |
|             {
 | |
|                 if (securityTokenHandler.CanWriteKeyIdentifierClause(keyIdentifierClause))
 | |
|                 {
 | |
|                     securityTokenHandler.WriteKeyIdentifierClause(writer, keyIdentifierClause);
 | |
|                     return;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             this.keyInfoSerializer.WriteKeyIdentifierClause(writer, keyIdentifierClause);
 | |
|         }
 | |
| 
 | |
|         private void AddToDictionaries(SecurityTokenHandler handler)
 | |
|         {
 | |
|             if (handler == null)
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("handler");
 | |
|             }
 | |
| 
 | |
|             bool firstSucceeded = false;
 | |
| 
 | |
|             string[] identifiers = handler.GetTokenTypeIdentifiers();
 | |
|             if (identifiers != null)
 | |
|             {
 | |
|                 foreach (string typeId in identifiers)
 | |
|                 {
 | |
|                     if (typeId != null)
 | |
|                     {
 | |
|                         this.handlersByIdentifier.Add(typeId, handler);
 | |
|                         firstSucceeded = true;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             Type type = handler.TokenType;
 | |
|             if (handler.TokenType != null)
 | |
|             {
 | |
|                 try
 | |
|                 {
 | |
|                     this.handlersByType.Add(type, handler);
 | |
|                 }
 | |
|                 catch
 | |
|                 {
 | |
|                     if (firstSucceeded)
 | |
|                     {
 | |
|                         this.RemoveFromDictionaries(handler);
 | |
|                     }
 | |
| 
 | |
|                     throw;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // Ensure that the handler knows which collection it is in.
 | |
|             handler.ContainingCollection = this;
 | |
| 
 | |
|             // Propagate this collection's STH configuration to the handler
 | |
|             // if the handler's configuration is unset.
 | |
|             if (handler.Configuration == null)
 | |
|             {
 | |
|                 handler.Configuration = this.configuration;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void RemoveFromDictionaries(SecurityTokenHandler handler)
 | |
|         {
 | |
|             string[] identifiers = handler.GetTokenTypeIdentifiers();
 | |
|             if (identifiers != null)
 | |
|             {
 | |
|                 foreach (string typeId in identifiers)
 | |
|                 {
 | |
|                     if (typeId != null)
 | |
|                     {
 | |
|                         this.handlersByIdentifier.Remove(typeId);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             Type type = handler.TokenType;
 | |
|             if (type != null && this.handlersByType.ContainsKey(type))
 | |
|             {
 | |
|                 this.handlersByType.Remove(type);
 | |
|             }
 | |
| 
 | |
|             // Ensure that the handler knows that it is no longer
 | |
|             // in a collection.
 | |
|             handler.ContainingCollection = null;
 | |
|             handler.Configuration = null;
 | |
|         }
 | |
|     }
 | |
| }
 |