//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IdentityModel;
using System.IdentityModel.Policy;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Security.Claims;
using System.ServiceModel;
using System.ServiceModel.Security;
using System.ServiceModel.Security.Tokens;
using System.Xml;
namespace System.IdentityModel.Tokens
{
///
/// This class derives from System.IdentityModel.Selectors.SecurityTokenSerializer and wraps a collection of SecurityTokenHandlers.
/// Any call to this serilaizer is delegated to the token handler and delegated to the base class if no token handler
/// is registered to handle this particular token or KeyIdentifier.
///
class SecurityTokenSerializerAdapter : SecurityTokenSerializer
{
SecurityTokenHandlerCollection _securityTokenHandlers;
///
/// Initializes an instance of
///
///
/// The containing the set of
///
public SecurityTokenSerializerAdapter(SecurityTokenHandlerCollection securityTokenHandlerCollection)
{
if (securityTokenHandlerCollection == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("securityTokenHandlerCollection");
}
_securityTokenHandlers = securityTokenHandlerCollection;
KeyInfoSerializer serializer = securityTokenHandlerCollection.KeyInfoSerializer as KeyInfoSerializer;
if (serializer != null)
{
serializer.InnerSecurityTokenSerializer = this;
}
}
///
/// Gets the SecurityTokenHandlerCollection.
///
public SecurityTokenHandlerCollection SecurityTokenHandlers
{
get
{
return _securityTokenHandlers;
}
}
///
/// Checks if one of the wrapped SecurityTokenHandlers or the base WSSecurityTokenSerializer
/// can read the security token.
///
/// Reader to a Security token.
/// 'True' if the serializer can read the given Security Token.
protected override bool CanReadTokenCore(XmlReader reader)
{
return _securityTokenHandlers.CanReadToken(reader);
}
///
/// Checks if one of the wrapped SecurityTokenHandlers or the base WSSecurityTokenSerializer
/// can write the given security token.
///
/// SecurityToken instance.
/// 'True' if the serializer can write the given security token.
protected override bool CanWriteTokenCore(SecurityToken token)
{
return _securityTokenHandlers.CanWriteToken(token);
}
///
/// Deserializes the SecurityToken from the given XmlReader.
///
/// Reader to a Security token.
/// Instance of SecurityTokenResolver.
/// 'True' if the serializer can read the given Security Token.
protected override SecurityToken ReadTokenCore(XmlReader reader, SecurityTokenResolver tokenResolver)
{
return _securityTokenHandlers.ReadToken(reader);
}
///
/// Serializes the SecurityToken to the XmlWriter.
///
/// XmlWriter to write to.
/// The SecurityToken to serializer.
/// The input parameter 'writer' or 'token' is null.
protected override void WriteTokenCore(XmlWriter writer, SecurityToken token)
{
_securityTokenHandlers.WriteToken(writer, token);
}
///
/// Checks if one of the wrapped SecurityTokenHandlers or the base WSSecurityTokenSerializer
/// can read the security key identifier.
///
/// Reader pointing at a Security Key Identifier {ds:Keyinfo}.
/// 'True' if the serializer can read the given Security Key Identifier.
/// The is null.
protected override bool CanReadKeyIdentifierCore(XmlReader reader)
{
return (reader.IsStartElement(XmlSignatureConstants.Elements.KeyInfo, XmlSignatureConstants.Namespace));
}
///
/// Reads an SecurityKeyIdentifier from a XML stream.
///
/// An XML reader positioned at an SecurityKeyIdentifier (ds: KeyInfo) as defined in 'http://www.w3.org/TR/xmldsig-core'.
/// SecurityKeyIdentifier.
/// The is null.
/// If the is not positioned at KeyInfo element.
protected override SecurityKeyIdentifier ReadKeyIdentifierCore(XmlReader reader)
{
if (reader == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
}
if (reader.IsStartElement(XmlSignatureConstants.Elements.KeyInfo, XmlSignatureConstants.Namespace))
{
KeyInfo keyInfo = new KeyInfo(this);
keyInfo.ReadXml(XmlDictionaryReader.CreateDictionaryReader(reader));
return keyInfo.KeyIdentifier;
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperXml(reader, SR.GetString(SR.ID4192));
}
}
protected override bool CanWriteKeyIdentifierCore(SecurityKeyIdentifier keyIdentifier)
{
return _securityTokenHandlers.KeyInfoSerializer == null ? false : _securityTokenHandlers.KeyInfoSerializer.CanWriteKeyIdentifier(keyIdentifier);
}
protected override void WriteKeyIdentifierCore(XmlWriter writer, SecurityKeyIdentifier keyIdentifier)
{
_securityTokenHandlers.KeyInfoSerializer.WriteKeyIdentifier(writer, keyIdentifier);
}
///
/// Checks if the wrapped SecurityTokenHandler can read the
/// SecurityKeyIdentifierClause.
///
/// Reader to a SecurityKeyIdentifierClause.
/// 'True' if the SecurityKeyIdentifierCause can be read.
/// The input parameter 'reader' is null.
protected override bool CanReadKeyIdentifierClauseCore(XmlReader reader)
{
foreach (SecurityTokenHandler securityTokenHandler in _securityTokenHandlers)
{
if (securityTokenHandler.CanReadKeyIdentifierClause(reader))
{
return true;
}
}
return (_securityTokenHandlers.KeyInfoSerializer == null) ? false : _securityTokenHandlers.KeyInfoSerializer.CanReadKeyIdentifierClause(reader);
}
///
/// Checks if the wrapped SecurityTokenHandler or the base WSSecurityTokenSerializer can write the
/// given SecurityKeyIdentifierClause.
///
/// SecurityKeyIdentifierClause to be checked.
/// 'True' if the SecurityTokenKeyIdentifierClause can be written.
/// The input parameter 'keyIdentifierClause' is null.
protected override bool CanWriteKeyIdentifierClauseCore(SecurityKeyIdentifierClause keyIdentifierClause)
{
foreach (SecurityTokenHandler securityTokenHandler in _securityTokenHandlers)
{
if (securityTokenHandler.CanWriteKeyIdentifierClause(keyIdentifierClause))
{
return true;
}
}
return (_securityTokenHandlers.KeyInfoSerializer == null) ? false : _securityTokenHandlers.KeyInfoSerializer.CanWriteKeyIdentifierClause(keyIdentifierClause);
}
///
/// Deserializes a SecurityKeyIdentifierClause from the given reader.
///
/// XmlReader to a SecurityKeyIdentifierClause.
/// The deserialized SecurityKeyIdentifierClause.
protected override SecurityKeyIdentifierClause ReadKeyIdentifierClauseCore(XmlReader reader)
{
return _securityTokenHandlers.ReadKeyIdentifierClause(reader);
}
///
/// Serializes the given SecurityKeyIdentifierClause in a XmlWriter.
///
/// XmlWriter to write into.
/// SecurityKeyIdentifierClause to be written.
protected override void WriteKeyIdentifierClauseCore(XmlWriter writer, SecurityKeyIdentifierClause keyIdentifierClause)
{
_securityTokenHandlers.WriteKeyIdentifierClause(writer, keyIdentifierClause);
}
}
}