This is a small, but still very useful class, whne working with WSE. It's written for WSE 3.0 but I'm quite sure it will work without code changes in WSE 2.0. The class is a custom UsernameTokenManager which is used by WSE to validate a UsernameToken (containing a username and password).
using System;
using System.Security.Principal;
using System.Web.Security;
using Microsoft.Web.Services3.Security.Tokens;
namespace IRM.Web.Services.Security.Tokens
{
/// <summary>
/// Represents a security token manager for <see cref="UsernameToken"/> security tokens that uses ASP.NET 2.0 <see cref="Membership.ValidateUser"/>.
/// </summary>
/// <remarks>
/// This class is used to parse <see cref="UsernameToken"/> security tokens within incoming SOAP messages. This implementation authenticates all
/// <b>UsernameToken</b> security tokens in a received SOAP message against the Membership functionality. It calls the <b>ValidateUser</b> function
/// for this authentication. If it succeeds, a generic principal is assigned to the <see cref="UsernameToken.Principal"/> property of the
/// <b>UsernameToken</b>. No roles are added to the <see cref="GenericPrincipal"/> object.
/// </remarks>
public class MembershipUsernameTokenManager : UsernameTokenManager
{
/// <summary>
/// Initializes a new instance of the <see cref="MembershipUsernameTokenManager"/> class.
/// </summary>
public MembershipUsernameTokenManager() : base()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MembershipUsernameTokenManager"/> class with configuration.
/// </summary>
/// <param name="configData">A <see cref="System.Xml.XmlNodeList"/> containing XML elements from a configuration file.</param>
public MembershipUsernameTokenManager(System.Xml.XmlNodeList configData)
: base(configData)
{
}
/// <summary>
/// Authenticates a <see cref="UsernameToken"/>.
/// </summary>
/// <param name="token">The <b>UsernameToken</b> to authenticate.</param>
/// <returns>The password of the authenticated <b>UsernameToken</b>.</returns>
/// <exception cref="ArgumentNullException"><see cref="UsernameToken.Username"/> is a null reference (<b>Nothing</b> in Visual Basic) or it is empty.</exception>
/// <exception cref="ArgumentNullException"><see cref="UsernameToken.Password"/> is a null reference (<b>Nothing</b> in Visual Basic) or it is empty.</exception>
protected override string AuthenticateToken(UsernameToken token)
{
IRM.Util.Guard.ArgumentNotNull(token, "token");
if (token.PasswordOption != PasswordOption.SendPlainText)
return null;
GenericPrincipal principal = LogonMembershipUser(token.Username, token.Password);
if (principal != null)
token.Principal = principal;
else
this.OnLogonUserFailed(token);
return token.Password;
}
private static GenericPrincipal LogonMembershipUser(string username, string password)
{
IRM.Util.Guard.ArgumentNotNullOrEmptyString(username, "username");
IRM.Util.Guard.ArgumentNotNullOrEmptyString(password, "password");
GenericPrincipal principal = null;
if (Membership.ValidateUser(username, password))
{
GenericIdentity identity = new GenericIdentity(username, "ASP.NET Membership");
principal = new GenericPrincipal(identity, Roles.GetRolesForUser());
}
return principal;
}
}
}
It would be quite likely that you would like to change the type of principal and identity objects you want to use in your code, but that is left as an exercise to the reader ;-).