2016-10-15 158 views
2

我目前正在與我的自定義CredentialsAuthProvider實施戰鬥一下。首先重要的是要說我正在編寫一個WPF客戶端作爲我的API的參考。Servicestack - 身份驗證問題

  1. 瀏覽器存儲Cookie,您可以配置如何處理它們,例如,當瀏覽器關閉時刪除。在Windows桌面上,您有Windows存儲Cookie的Environment.SpecialFolder.Cookies。但是我從ServiceStack找不到任何東西。那麼它不會在Windows桌面應用上存儲任何內容?我看到有一個client.CookieContainer,我在登錄後發現三個餅乾。
  2. 我可以在驗證過程中以某種方式將屬性添加到此cookie嗎?如果是這樣如何?目前我使用AuthenticationResponse.Meta字典傳遞更多信息:

    public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request) 
    { 
        var authResponse = (AuthenticateResponse)base.Authenticate(authService, session, request); 
        authResponse.Meta = new Dictionary<string, string>(); 
        authResponse.Meta.Add("Test", "TestValue"); 
        return authResponse; 
    } 
    
  3. 最後:是我的派生類CredentialsAuthProvider線的一個實例,安全嗎?在TryAuthenticate(...)我建立一個數據庫連接並檢索一個包含散列密碼等所有信息的對象。但是我只能將這些信息填充到OnAuthenticated(....)中的會話對象和/或覆蓋Authenticate(...)。如果可能的話,我不想再次進行數據庫調用來再次檢索同一個對象。因此,它是安全的聲明成員user填補它在TryAuthenticate和其他覆蓋方法,像這樣重複使用它:

    public class BediCredentialsAuthProvider : CredentialsAuthProvider 
    { 
        private AppUser user = null; 
    
        public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request) 
        { 
         var authResponse = (AuthenticateResponse)base.Authenticate(authService, session, request); 
         authResponse.Meta = new Dictionary<string, string>(); 
         authResponse.Meta.Add("ValueA", user.ValueA); 
         // ... add more properties from user object 
         return authResponse; 
        } 
    
        public override bool TryAuthenticate(IServiceBase authService, string userName, string password) 
        { 
         AppUser user = null; 
         using (var session = NhSessionFactories.OpenSession(TopinConstants.TopInDbFactory)) 
         { 
          using (var transaction = session.BeginTransaction()) 
          { 
           try 
           { 
            var appUserRepo = new AccountManagementRepository(session); 
            user = appUserRepo.GetAppUser(userName); // get user from database using NHibernate 
            transaction.Commit(); 
            session.Close(); 
           } 
           catch (Exception ex) 
           { 
            Log.Error($"Error retrieving user {user} to authenticate. Error: {ex}"); 
            throw; 
           } 
          } 
         } 
         // do some logic to test passed credentials and return true or false 
         } 
    
        public override IHttpResult OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, 
                  Dictionary<string, string> authInfo) 
        { 
         session.DisplayName = user.DisplayName; 
         session.FirstName = user.Firstname; 
         session.LastName = user.Lastname; 
         session.Email = user.EmailAddress; 
         // etc..... 
         return base.OnAuthenticated(authService, session, tokens, authInfo); 
        } 
    } 
    

回答

2

可以填充ServiceStack服務客戶端的Cookie就像你除了它一個瀏覽器只保留永久會話ID,您需要與RememberMe=true認證,如:

var response = client.Post(new Authenticate { 
    provider = "credentials", 
    UserName = ..., 
    Password = ..., 
    RememberMe = true, 
}); 

這將節省驗證的用戶會話對ss-pid永久性的Cookie中的HttpWebRequest的CookieContainer和在每個後續請求中發送。

var httpRes = authService.Request.Response; 
httpRes.SetPermanentCookie(cookieName, cookieValue); 

安全我的派生類CredentialsAuthProvider線的一個實例:

您可以從authService設置在OnAuthenticated自己的永久餅乾?

不相同AuthProvider單一實例,用於驗證每個請求,所以你不能保持對實例本身存儲的任何變量,需要將其刪除:

//private AppUser user = null; //Instance variables are not ThreadSafe 

如果你想通過項目並通過請求管道訪問它們,您可以將它們存儲在IRequest.Items詞典中,例如:

authService.Request.Items["AppUser"] = user;