2011-05-04 82 views
1

我有下面的代碼(基於網絡上的許多例子)的在WCF中執行自定義用戶名密碼驗證的最佳方式是什麼?

public class UserNameValidator : UserNamePasswordValidator 
{ 
    /// <summary> 
    /// Validates the user name and password combination. 
    /// </summary> 
    /// <param name="userName">The user name.</param> 
    /// <param name="password">The password.</param> 
    public override void Validate(string userName, string password) 
    { 
     // validate arguments 
     if (string.IsNullOrEmpty(userName)) 
      throw new ArgumentNullException("userName"); 
     if (string.IsNullOrEmpty(password)) 
      throw new ArgumentNullException("password"); 

     UserCredential user = InMemoryUserStore.Get(userName); 
     if (user == null) 
     { 
      using (DataAccessAdapter da = new DataAccessAdapter()) 
      { 
       LinqMetaData db = new LinqMetaData(da); 
       var newUserCredential = (from u in db.User 
             where u.Username == userName 
             select new UserCredential 
             { 
              UserName = u.Username, 
              PasswordHash = u.PasswordHash, 
              PasswordSalt = u.PasswordSalt 
             }).FirstOrDefault(); 
       if (newUserCredential == null) 
       { 
        throw new SecurityTokenException("Unknown username or password"); 
       } 
       else 
       { 
        InMemoryUserStore.Add(newUserCredential); 
        user = newUserCredential; 
       } 
      } 
     } 

     //Validate Password 
     PasswordHash p = new PasswordHash(user.PasswordSalt, user.PasswordHash); 
     if (!p.Verify(password)) 
     { 
      throw new SecurityTokenException("Unknown username or password"); 
     } 
    } 
} 

這是做的最好的方法是什麼?

+0

自定義驗證,如果通道不被認證,纔會調用。一旦獲得認證(即無需例外地通過此代碼),它在通道打開時不會再次調用此方法。 所以整個InMemoryUserStore是不必要的 – 2011-05-04 11:05:54

回答

1

由於只能調用一次自定義驗證器,因此不需要InMemoryStore。下面的代碼就是我們正在使用的代碼,並且它在生產中非常出色。

public override void Validate(string userName, string password) 
    { 
     // validate arguments 
     if (string.IsNullOrEmpty(userName)) 
      throw new ArgumentNullException("userName"); 
     if (string.IsNullOrEmpty(password)) 
      throw new ArgumentNullException("password"); 

     using (DataAccessAdapter da = new DataAccessAdapter()) 
     { 
      LinqMetaData db = new LinqMetaData(da); 
      var userCredential = (from u in db.User 
            where u.Username == userName 
            select new UserCredential 
            { 
             UserName = u.Username, 
             PasswordHash = u.PasswordHash, 
             PasswordSalt = u.PasswordSalt 
            }).FirstOrDefault(); 
      if (userCredential == null) 
      { 
       throw new SecurityTokenException("Unknown username or password"); 
      } 

      //Validate Password 
      PasswordHash p = new PasswordHash(userCredential.PasswordSalt, userCredential.PasswordHash); 
      if (!p.Verify(password)) 
      { 
       throw new SecurityTokenException("Unknown username or password"); 
      } 
     } 
    } 

呼叫一旦認證,可以使用以下命令來創建自定義用戶:

public bool Evaluate(EvaluationContext evaluationContext, ref object state) 
    { 
     // get the authenticated client identity 
     IIdentity client = GetClientIdentity(evaluationContext);    

     // add roles etc 
     .... 

     evaluationContext.Properties["Principal"] = new CustomPrincipal(client, roles.ToArray(), userId, email, client.Name); 

     return true; 
    } 
相關問題