//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
using System.Xml;
namespace System.IdentityModel.Tokens
{
///
/// Defines a SecurityTokenHandler for Username Password Tokens.
///
public abstract class UserNameSecurityTokenHandler : SecurityTokenHandler
{
bool _retainPassword;
///
/// Initializes an instance of
///
protected UserNameSecurityTokenHandler()
{
}
///
/// Controls if the password will be retained in the bootstrap token that is
/// attached to the ClaimsIdentity in ValidateToken. The default is false.
///
public virtual bool RetainPassword
{
get
{
return _retainPassword;
}
set
{
_retainPassword = value;
}
}
///
/// Checks the given XmlReader to verify that it is pointing to a Username
/// token.
///
/// XmlReader pointing to SecurityToken.
/// True if the reader is pointing to a Username SecurityToken.
/// The given reader is null.
public override bool CanReadToken(XmlReader reader)
{
if (reader == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
}
return reader.IsStartElement(WSSecurity10Constants.Elements.UsernameToken, WSSecurity10Constants.Namespace);
}
///
/// Returns true to indicate that the handler can write UsernameSecurityToken.
///
public override bool CanWriteToken
{
get
{
return true;
}
}
///
/// Get the System.Type of the SecurityToken that this handler can handle.
///
public override Type TokenType
{
get
{
return typeof(UserNameSecurityToken);
}
}
///
/// Get the TokenTypeIdentifier of the token that this handler can work with.
///
public override string[] GetTokenTypeIdentifiers()
{
return new string[] { SecurityTokenTypes.UserName };
}
///
/// Reads the UsernameSecurityToken from the given XmlReader.
///
/// XmlReader pointing to the SecurityToken.
/// An instance of .
/// The parameter 'reader' is null.
/// The token cannot be read.
/// The Password was not in plain text format.
/// An unknown element was found in the SecurityToken or
/// the username was not specified.
public override SecurityToken ReadToken(XmlReader reader)
{
if (reader == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
}
if (!CanReadToken(reader))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new XmlException(
SR.GetString(
SR.ID4065,
WSSecurity10Constants.Elements.Username,
WSSecurity10Constants.Namespace,
reader.LocalName,
reader.NamespaceURI)));
}
string id = null;
string userName = null;
string password = null;
reader.MoveToContent();
id = reader.GetAttribute(WSUtilityConstants.Attributes.IdAttribute, WSUtilityConstants.NamespaceURI);
reader.ReadStartElement(WSSecurity10Constants.Elements.UsernameToken, WSSecurity10Constants.Namespace);
while (reader.IsStartElement())
{
if (reader.IsStartElement(WSSecurity10Constants.Elements.Username, WSSecurity10Constants.Namespace))
{
userName = reader.ReadElementString();
}
else if (reader.IsStartElement(WSSecurity10Constants.Elements.Password, WSSecurity10Constants.Namespace))
{
string type = reader.GetAttribute(WSSecurity10Constants.Attributes.Type, null);
if (!string.IsNullOrEmpty(type) && !StringComparer.Ordinal.Equals(type, WSSecurity10Constants.UPTokenPasswordTextValue))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.ID4059, type, WSSecurity10Constants.UPTokenPasswordTextValue)));
}
password = reader.ReadElementString();
}
else if (reader.IsStartElement(WSSecurity10Constants.Elements.Nonce, WSSecurity10Constants.Namespace))
{
// Nonce can be safely ignored
reader.Skip();
}
else if (reader.IsStartElement(WSUtilityConstants.ElementNames.Created, WSUtilityConstants.NamespaceURI))
{
// wsu:Created can be safely ignored
reader.Skip();
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.ID4060, reader.LocalName, reader.NamespaceURI, WSSecurity10Constants.Elements.UsernameToken, WSSecurity10Constants.Namespace)));
}
}
reader.ReadEndElement();
if (string.IsNullOrEmpty(userName))
{
throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4061));
}
return string.IsNullOrEmpty(id) ?
new UserNameSecurityToken(userName, password) :
new UserNameSecurityToken(userName, password, id);
}
///
/// Writes the given UsernameSecurityToken to the XmlWriter.
///
/// XmlWriter to write the token to.
/// SecurityToken to be written.
/// The given token is not a UsernameSecurityToken.
/// The parameter 'writer' or 'token' is null.
public override void WriteToken(XmlWriter writer, SecurityToken token)
{
if (writer == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
}
if (token == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
}
UserNameSecurityToken usernameSecurityToken = token as UserNameSecurityToken;
if (usernameSecurityToken == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("token", SR.GetString(SR.ID0018, typeof(UserNameSecurityToken)));
}
// ...
writer.WriteElementString(
WSSecurity10Constants.Elements.Username,
WSSecurity10Constants.Namespace,
usernameSecurityToken.UserName
);
// ...
if (usernameSecurityToken.Password != null)
{
writer.WriteStartElement(
WSSecurity10Constants.Elements.Password,
WSSecurity10Constants.Namespace
);
writer.WriteAttributeString(
WSSecurity10Constants.Attributes.Type,
null,
WSSecurity10Constants.UPTokenPasswordTextValue
);
writer.WriteString(usernameSecurityToken.Password);
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.Flush();
}
}
}