2016-10-15 13 views
2

私は現在、カスタムCredentialsAuthProviderの実装で少し戦っています。まず、私のAPIのリファレンスとしてWPFクライアントを書いていると言っておくことが重要です。Servicestack - 認証質問

  1. ブラウザにはCookieが保存されています。ブラウザはCookieを保存しています。ブラウザが閉じられると削除されます。 Windowsデスクトップでは、WindowsがCookieを保存するEnvironment.SpecialFolder.Cookiesがあります。しかしServiceStackからは何も見つかりませんでした。では、Windowsデスクトップアプリケーションに何も保存しないのですか? client.CookieContainerがあり、ログイン後に3つのCookieが見つかりました。
  2. 認証中にこのクッキーに何らかのプロパティを追加できますか?もしそうなら、どのように?現在、私は、追加の情報を転送する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(...)私は、DB接続を作成し、ハッシュされたパスワードなどのすべての情報を含むオブジェクトを取得します。しかし、この情報はセッションオブジェクトにOnAuthenticated(....)および/またはAuthenticate(...)にのみ書き込むことができます。可能であれば、別のDB呼び出しを行って同じオブジェクトを再度取得したくありません。だから、TryAuthenticateでそれを埋めるなどのような他の上書きされた方法でそれを再利用するメンバーuserを宣言しても安全である:

    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サービスクライアントのクッキーを読み込むことができ、それを除いて、ブラウザのみ保持しますあなたはRememberMe=trueで認証する必要があります恒久的なセッションのIds、例えば:HttpWebRequestのCookieContainerにss-pid永久クッキーに対する認証されたユーザー・セッションを保存します

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

とその後のすべてのリクエストで送信されます。

あなたがしてauthServiceからOnAuthenticatedで独自の永久クッキーを設定することができます。

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

は安全な私の派生CredentialsAuthProviderクラススレッドのインスタンスですか?

ません同じAuthProviderシングルトンインスタンスは、インスタンス自体上の任意の格納された変数を維持することはできませんので、それぞれの要求を認証するために使用されており、削除する必要があります:あなたがアイテムを渡したい場合は

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

をリクエストパイプライン全体にアクセスして、辞書に保存することができます。たとえば、

authService.Request.Items["AppUser"] = user; 
関連する問題