My current method to verify the username and password (Tokens) in WSE is as follows:
public override void VerifyToken(SecurityToken token1)
{
if (token1 is UsernameToken)
{
string u1 = (token1 as UsernameToken).Username;
string p1 = (token1 as UsernameToken).Password;
// see if this user is already authenticated
UsernameToken token2 = TokenCache[u1] as UsernameToken;
if ((token2 != null) && token2.IsCurrent && (token2.Password == p1))
{
// less than 30s?
if ((DateTime.Now - token2.Created) < TimeSpan.FromSeconds(30))
return;
else
// no - remove from cache
RemoveFromCache(token1);
}
// not cached, so actually check
// NB Two or more requests for same user at about same time may all fail test above
// and thus all will call ValidateUser. But then they will all call CacheSecurityToken below,
// which is OK - the last one wins.
if (Membership.ValidateUser(u1, p1))
{
Cache(token1);
return;
}
// not authenticated
throw new Exception("Authentication failed for " + u1);
}
Any idea how can I make changes in WCF? I Have used Microsoft.Web.Service3 WSE assembly - don't want to use that. Want to get rid of UsernameToken from my entire solution.
I have managed verify my security credentials on each webservice call. I have used Directory key-value pair to cache the credentials - if anyone looking for the similar, it would help.
public class SecurityManager : UserNamePasswordValidator
{
//cacheCredentials stores username and password
static Dictionary<string, string> cacheCredentials = new Dictionary<string, string>();
//cacheTimes stores username and time that username added to dictionary.
static Dictionary<string, DateTime> cacheTimes = new Dictionary<string, DateTime>();
public override void Validate(string userName, string password)
{
if (userName == null || password == null)
{
throw new ArgumentNullException();
}
if (cacheCredentials.ContainsKey(userName))
{
if ((cacheCredentials[userName] == password) && ((DateTime.Now - cacheTimes[userName]) < TimeSpan.FromSeconds(30)))// && timespan < 30 sec - TODO
return;
cacheCredentials.Remove(userName);
cacheTimes.Remove(userName);
}
if (Membership.ValidateUser(userName, password))
{
//cache usename(key) and password(value)
cacheCredentials.Add(userName, password);
//cache username(key), time that username added to dictionary
cacheTimes.Add(userName, DateTime.Now);
return;
}
throw new FaultException("Authentication failed for the user");
}
}