3

因此,我根据此处的示例使用 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 方法,我如何/使用什么来访问/检索数据库中的用户信息?

4

2 回答 2

6

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

在查看 CredentialsAuthProvider 的实际代码之前,我一直在为同样的困境苦苦挣扎(这通常是了解 ServiceStack 中的工作原理的唯一方法)。OnAuthenticated 是在 Authenticate 方法内的 TryAuthenticate 之后立即调用的,所以我认为没有必要像@mythz 在他的示例中所建议的那样在 OnAuthenticated 中进行所有数据库调用。相反,我将填充 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 以便将 cookie 保存在 HTTP 响应中(我假设来自同一浏览器的后续请求需要经过身份验证),因为基本实现仅在 IOC 容器中找到 IUserAuthRepository 时才设置 cookie ,在我的情况下不会发生,因为我使用自己的存储库。所以我的实现现在看起来像这样:

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的另一个很好的例子是 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;
    }
}
于 2012-09-26T04:38:47.507 回答