2012-09-26 208 views
3

所以我创建使用ServiceStack按照设在这里的例子定制CredentialsAuthProvider数据: https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization填充IAuthSession从数据库

我的东西工作认证的一面,但我不知道我如何填充在OnAuthenticated方法中使用数据库中的数据进行会话。在这个例子中,他们显示以下内容:

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

在TryAuthenticate方法我的用户名/密码,我可以用它来对数据库对用户进行认证,但一旦进入到OnAuthenticated方法,怎样/什么我用来从数据库访问/检索用户信息吗?

回答

5

ServiceStack的CustomUserSession的另一个很好的例子是SocialBootstrapApi项目。而不是拉动信息出来的数据,它提取出来的UserSession的信息,并填充使用注册DB厂自己的自定义用户表从APPHOST IOC解决:

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; 
    } 
} 
+0

谢谢。我使用这个:var user = DbFactory.Run(db => GetUserByUserName(db,session.UserAuthName)); – fergs

6

我知道这是一个较旧的线程,但它可能仍然是相关的,因为不幸的是没有太大的改善自2012年9月以来,ServiceStack文档的可用性,示例或e在代码中注释。 (@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为了节省在HTTP响应中的Cookie(我假设是必需的对于来自同一浏览器的后续请求进行身份验证),因为基本实现只在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:请让我知道,如果以上有道理或没有。

+0

+1这就是我所缺少的:一旦我使用身份验证服务成功登录后填充真实会话。 – ashes999