e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
238 lines
9.2 KiB
C#
238 lines
9.2 KiB
C#
//------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//------------------------------------------------------------
|
|
|
|
using System.Xml;
|
|
|
|
namespace System.IdentityModel.Tokens
|
|
{
|
|
/// <summary>
|
|
/// Defines a SecurityTokenHandler for Username Password Tokens.
|
|
/// </summary>
|
|
public abstract class UserNameSecurityTokenHandler : SecurityTokenHandler
|
|
{
|
|
bool _retainPassword;
|
|
|
|
/// <summary>
|
|
/// Initializes an instance of <see cref="UserNameSecurityTokenHandler"/>
|
|
/// </summary>
|
|
protected UserNameSecurityTokenHandler()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Controls if the password will be retained in the bootstrap token that is
|
|
/// attached to the ClaimsIdentity in ValidateToken. The default is false.
|
|
/// </summary>
|
|
public virtual bool RetainPassword
|
|
{
|
|
get
|
|
{
|
|
return _retainPassword;
|
|
}
|
|
set
|
|
{
|
|
_retainPassword = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks the given XmlReader to verify that it is pointing to a Username
|
|
/// token.
|
|
/// </summary>
|
|
/// <param name="reader">XmlReader pointing to SecurityToken.</param>
|
|
/// <returns>True if the reader is pointing to a Username SecurityToken.</returns>
|
|
/// <exception cref="ArgumentNullException">The given reader is null.</exception>
|
|
public override bool CanReadToken(XmlReader reader)
|
|
{
|
|
if (reader == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
|
|
}
|
|
|
|
return reader.IsStartElement(WSSecurity10Constants.Elements.UsernameToken, WSSecurity10Constants.Namespace);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true to indicate that the handler can write UsernameSecurityToken.
|
|
/// </summary>
|
|
public override bool CanWriteToken
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the System.Type of the SecurityToken that this handler can handle.
|
|
/// </summary>
|
|
public override Type TokenType
|
|
{
|
|
get
|
|
{
|
|
return typeof(UserNameSecurityToken);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the TokenTypeIdentifier of the token that this handler can work with.
|
|
/// </summary>
|
|
public override string[] GetTokenTypeIdentifiers()
|
|
{
|
|
return new string[] { SecurityTokenTypes.UserName };
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads the UsernameSecurityToken from the given XmlReader.
|
|
/// </summary>
|
|
/// <param name="reader">XmlReader pointing to the SecurityToken.</param>
|
|
/// <returns>An instance of <see cref="UserNameSecurityToken"/>.</returns>
|
|
/// <exception cref="ArgumentNullException">The parameter 'reader' is null.</exception>
|
|
/// <exception cref="XmlException">The token cannot be read.</exception>
|
|
/// <exception cref="NotSupportedException">The Password was not in plain text format.</exception>
|
|
/// <exception cref="InvalidOperationException">An unknown element was found in the SecurityToken or
|
|
/// the username was not specified.</exception>
|
|
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);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Writes the given UsernameSecurityToken to the XmlWriter.
|
|
/// </summary>
|
|
/// <param name="writer">XmlWriter to write the token to.</param>
|
|
/// <param name="token">SecurityToken to be written.</param>
|
|
/// <exception cref="InvalidOperationException">The given token is not a UsernameSecurityToken.</exception>
|
|
/// <exception cref="ArgumentNullException">The parameter 'writer' or 'token' is null.</exception>
|
|
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)));
|
|
}
|
|
|
|
// <wsse:UsernameToken
|
|
writer.WriteStartElement(
|
|
WSSecurity10Constants.Elements.UsernameToken,
|
|
WSSecurity10Constants.Namespace
|
|
);
|
|
if (!string.IsNullOrEmpty(token.Id))
|
|
{
|
|
// wsu:Id="..."
|
|
writer.WriteAttributeString(
|
|
WSUtilityConstants.Attributes.IdAttribute,
|
|
WSUtilityConstants.NamespaceURI,
|
|
token.Id
|
|
);
|
|
}
|
|
// <wsse:Username>...</wsse:Username>
|
|
writer.WriteElementString(
|
|
WSSecurity10Constants.Elements.Username,
|
|
WSSecurity10Constants.Namespace,
|
|
usernameSecurityToken.UserName
|
|
);
|
|
|
|
// <wsse:Password>...</wsse:Password>
|
|
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();
|
|
}
|
|
}
|
|
}
|