//-----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------
namespace System.IdentityModel.Tokens
{
using System;
using System.Collections.ObjectModel;
using System.Xml;
///
/// Represents the Assertion element specified in [Saml2Core, 2.3.3].
///
public class Saml2Assertion
{
private Saml2Advice advice;
private Saml2Conditions conditions;
private EncryptingCredentials encryptingCredentials;
private Collection externalEncryptedKeys = new Collection();
private Saml2Id id = new Saml2Id();
private DateTime issueInstant = DateTime.UtcNow;
private Saml2NameIdentifier issuer;
private SigningCredentials signingCredentials;
private XmlTokenStream sourceData;
private Collection statements = new Collection();
private Saml2Subject subject;
private string version = "2.0";
///
/// Creates an instance of a Saml2Assertion.
///
/// Issuer of the assertion.
public Saml2Assertion(Saml2NameIdentifier issuer)
{
if (issuer == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuer");
}
this.issuer = issuer;
}
///
/// Gets or sets additional information related to the assertion that assists processing in certain
/// situations but which may be ignored by applications that do not understand the
/// advice or do not wish to make use of it. [Saml2Core, 2.3.3]
///
public Saml2Advice Advice
{
get { return this.advice; }
set { this.advice = value; }
}
///
/// Gets a value indicating whether this assertion was deserialized from XML source
/// and can re-emit the XML data unchanged.
///
///
///
/// The default implementation preserves the source data when read using
/// Saml2AssertionSerializer.ReadAssertion and is willing to re-emit the
/// original data as long as the Id has not changed from the time that
/// assertion was read.
///
///
/// Note that it is vitally important that SAML assertions with different
/// data have different IDs. If implementing a scheme whereby an assertion
/// "template" is loaded and certain bits of data are filled in, the Id
/// must be changed.
///
///
/// 'True' if this instance can write the source data.
public virtual bool CanWriteSourceData
{
get { return null != this.sourceData; }
}
///
/// Gets or sets conditions that must be evaluated when assessing the validity of and/or
/// when using the assertion. [Saml2Core 2.3.3]
///
public Saml2Conditions Conditions
{
get { return this.conditions; }
set { this.conditions = value; }
}
///
/// Gets or sets the credentials used for encrypting the assertion. The key
/// identifier in the encrypting credentials will be used for the
/// embedded EncryptedKey in the EncryptedData element.
///
public EncryptingCredentials EncryptingCredentials
{
get { return this.encryptingCredentials; }
set { this.encryptingCredentials = value; }
}
///
/// Gets additional encrypted keys which will be specified external to the
/// EncryptedData element, as children of the EncryptedAssertion element.
///
public Collection ExternalEncryptedKeys
{
get { return this.externalEncryptedKeys; }
}
///
/// Gets or sets the identifier for this assertion. [Saml2Core, 2.3.3]
///
public Saml2Id Id
{
get
{
return this.id;
}
set
{
if (null == value)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
}
this.id = value;
this.sourceData = null;
}
}
///
/// Gets or sets the time instant of issue in UTC. [Saml2Core, 2.3.3]
///
public DateTime IssueInstant
{
get { return this.issueInstant; }
set { this.issueInstant = DateTimeUtil.ToUniversalTime(value); }
}
///
/// Gets or sets the as the authority that is making the claim(s) in the assertion. [Saml2Core, 2.3.3]
///
public Saml2NameIdentifier Issuer
{
get
{
return this.issuer;
}
set
{
if (value == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
}
this.issuer = value;
}
}
///
/// Gets or sets the used by the issuer to protect the integrity of the assertion.
///
public SigningCredentials SigningCredentials
{
get { return this.signingCredentials; }
set { this.signingCredentials = value; }
}
///
/// Gets or sets the of the statement(s) in the assertion. [Saml2Core, 2.3.3]
///
public Saml2Subject Subject
{
get { return this.subject; }
set { this.subject = value; }
}
///
/// Gets the (s) regarding the subject.
///
public Collection Statements
{
get { return this.statements; }
}
///
/// Gets the version of this assertion. [Saml2Core, 2.3.3]
///
///
/// In this version of the Windows Identity Foundation, only version "2.0" is supported.
///
public string Version
{
get { return this.version; }
}
///
/// Writes the source data, if available.
///
/// When no source data is available
/// A for writting the data.
public virtual void WriteSourceData(XmlWriter writer)
{
if (!this.CanWriteSourceData)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(SR.GetString(SR.ID4140)));
}
// This call will properly just reuse the existing writer if it already qualifies
XmlDictionaryWriter dictionaryWriter = XmlDictionaryWriter.CreateDictionaryWriter(writer);
this.sourceData.SetElementExclusion(null, null);
this.sourceData.GetWriter().WriteTo(dictionaryWriter, new DictionaryManager());
}
///
/// Captures the XML source data from an EnvelopedSignatureReader.
///
///
/// The EnvelopedSignatureReader that was used to read the data for this
/// assertion should be passed to this method after the </Assertion>
/// element has been read. This method will preserve the raw XML data
/// that was read, including the signature, so that it may be re-emitted
/// without changes and without the need to re-sign the data. See
/// CanWriteSourceData and WriteSourceData.
///
/// that contains the data for the assertion.
internal virtual void CaptureSourceData(EnvelopedSignatureReader reader)
{
if (null == reader)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
}
this.sourceData = reader.XmlTokens;
}
}
}