3

そこで、 https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorizationにある例に従って、ServiceStackを使用してカスタムCredentialsAuthProviderを作成しました 。

私は物事の認証側を機能させていますが、OnAuthenticatedメソッドでデータベースからのデータをセッションに入力する方法がわかりません。この例では、次のように表示されます。

     //Fill the IAuthSession with data which you want to retrieve in the app eg:
    session.FirstName = "some_firstname_from_db"; 

TryAuthenticateメソッドには、データベースに対してユーザーを認証するために使用できるユーザー名/パスワードがありますが、OnAuthenticatedメソッドに移行したら、データベースからユーザー情報にアクセス/取得するためにどのように/何を使用しますか?

4

2 に答える 2

6

これは古いスレッドであることは承知していますが、ServiceStack ドキュメントの入手可能性、例の明確さ、またはコード内のコメントでさえ、残念ながら 2012 年 9 月以降あまり改善されていないため、依然として関連性がある可能性があります。(@mythz:すべてのクラスとメソッドに意味のある要約を追加していただければ非常に助かります。)

CredentialsAuthProvider の実際のコードを見るまで、私は同じジレンマに苦しんでいました (これは、一般に、ServiceStack での動作を理解する唯一の方法です)。OnAuthenticated は、Authenticate メソッド内の TryAuthenticate の直後に呼び出されるため、@mythz が彼の例で示唆しているように、OnAuthenticated ですべての DB 呼び出しを行う必要はないと考えました。代わりに、次のように、IAuthSession オブジェクトを実装するコードを TryAuthenticate の実装に配置しました。

public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
    try
    {
        // Use my own repo to authenticate the user.
        var userRepo = authService.TryResolve<IUserRepository>();
        var user = userRepo.Authenticate(userName, password);

        // Populate session properties with data from my user POCO.
        var session = authService.GetSession();
        session.Id = user.CurrentSession.ID.ToString();
        session.IsAuthenticated = true;
        session.CreatedAt = DateTime.UtcNow;
        session.DisplayName = session.FirstName = session.LastName = user.FullName;
        session.UserAuthName = session.UserName = user.Username;
        session.UserAuthId = user.ID.ToString();
    }
    catch (Exception ex)
    {
        // Log the exception, etc....
        return false;
    }
    return true;
}

ただし、HTTP 応答で Cookie を保存するには、OnAuthenticated をオーバーライドする必要があります (同じブラウザーからの後続の要求を認証するために必要であると想定しています)。 、私の場合は、自分のリポジトリを使用しているため発生しません。したがって、私の実装は次のようになります。

public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary<string, string> authInfo)
{
    try
    {
        // Save the browser cookie.
        var httpRes = authService.RequestContext.Get<IHttpResponse>();
        if (httpRes != null)
        {
            httpRes.Cookies.AddPermanentCookie(HttpHeaders.XUserAuthId, session.UserAuthId);
        }

        // Save the user session object (ServiceStack stores it in the in-memory cache).
        authService.SaveSession(session, SessionExpiry);
    }
    catch (Exception ex)
    {
        // Log the exception, etc....
    }
}

@mythz:上記が理にかなっているのかどうか教えてください。

于 2013-06-25T16:30:04.753 に答える
5

ServiceStack のCustomUserSessionのもう 1 つの良い例は、SocialBootstrapApi プロジェクトにあります。データから情報を引き出すのではなく、UserSession から情報を抽出し、AppHost IOC から解決された登録済みの DB ファクトリを使用して、独自のカスタム ユーザー テーブルを設定します。

authService.TryResolve<IDbConnectionFactory>().Run(db => db.Save(user));

これを使用してユーザーのセッションからデータを抽出して保存するのではなく、登録済みの依存関係のいずれかを使用してデータをフェッチし、セッションに次のものを入力することもできます。

public override void OnAuthenticated(
    IServiceBase authService, 
    IAuthSession session, 
    IOAuthTokens tokens, 
    Dictionary<string, string> authInfo)
{
    using (var db = authService.TryResolve<IDbConnectionFactory>().OpenDbConnection()) 
    {
        var user = db.Id<MyUser>(session.UserId);
        session.FirstName = user.FirstName;
    }
}
于 2012-09-26T04:38:47.507 に答える