使用数据库中的数据填充IAuthSession

时间:2012-09-26 03:10:27

标签: servicestack

所以我根据以下示例使用ServiceStack创建了一个自定义CredentialsAuthProvider: https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization

我的身份验证方面有效,但我不确定如何在OnAuthenticated方法中使用数据库中的数据填充会话。在示例中,它们显示以下内容:

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

在TryAuthenticate方法中,我有用户名/密码,我可以用来根据数据库对用户进行身份验证,但是一旦进入OnAuthenticated方法,我将如何/如何使用来访问/检索用户信息数据库?

2 个答案:

答案 0 :(得分:6)

我知道这是一个较旧的主题,但它可能仍然具有相关性,但遗憾的是,自2012年9月以来,ServiceStack文档的可用性,示例的清晰度甚至代码中的注释都没有太大改进。 ( @mythz:如果你们可以为你们所有的类和方法添加有意义的摘要,将会非常有帮助。)

我一直在努力解决相同的困境,直到我查看了CredentialsAuthProvider的实际代码(这通常是理解ServiceStack中工作方式的唯一方法)。在Authenticate方法中TryAuthenticate之后立即调用OnAuthenticated,所以我认为没有必要在OnAuthenticated中进行所有数据库调用,因为@mythz在他的示例中建议。相反,我将填充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;
}

但是,您仍然必须重写OnAuthenticated,以便在HTTP响应中保存cookie(我认为这是来自同一浏览器的后续请求需要进行身份验证的原因),因为基本实现仅在找到IUserAuthRepository时才设置cookie IOC容器,在我的情况下不会发生,因为我使用自己的存储库。所以我的实现现在看起来像这样:

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:如果上述内容有意义,请告诉我。

答案 1 :(得分:5)

ServiceStack CustomUserSession的另一个很好的例子是SocialBootstrapApi项目。它不是从数据中提取信息,而是从UserSession中提取信息,并使用从AppHost IOC解析的已注册DB Factory填充其自己的自定义用户表:

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;
    }
}
相关问题