代码之家  ›  专栏  ›  技术社区  ›  Brian Ogden

如何正确实现IUserSessionSource-ServiceStack

  •  1
  • Brian Ogden  · 技术社区  · 6 年前

    已将新功能添加到 ServiceStack 5.0 允许在没有 IAuthRepository , see here

    我不知道ServiceStack 5.0的这个新特性有什么可用的文档,我有一个自定义的AuthProvider,我不知道如何实现 IUserSessionSource .

    目前,我的IUserSessionSource。GetUserSession实现甚至没有被调用,我已经清除了Nuget缓存,并从ServiceStacks Nuget服务器检索到了最新的5.0 libs。

    这是我的代码:

    public class CustomCredentialsAuthProvider : CredentialsAuthProvider, IUserSessionSource
    {
        private readonly ITsoContext _tsoContext;
        private IEnumerable<Claims> _claims;
    
        public CustomCredentialsAuthProvider(ITsoContext tsoContext)
        {
            _tsoContext = tsoContext;
        }
    
        public override bool TryAuthenticate(IServiceBase authService,
            string userName, string password)
        {
            _claims = _tsoContext.AuthenticateUser(userName, password);
    
            return _claims.Any();
        }
    
        /// <summary>
        /// ref: https://github.com/ServiceStack/ServiceStack/blob/a5bc5f5a96fb990b69dcad9dd5e95e688477fd94/src/ServiceStack/Auth/CredentialsAuthProvider.cs#L236
        /// ref: https://stackoverflow.com/questions/47403428/refreshtoken-undefined-after-successful-authentication-servicestack/47403514#47403514
        /// </summary>
        /// <param name="authService"></param>
        /// <param name="session"></param>
        /// <param name="tokens"></param>
        /// <param name="authInfo"></param>
        /// <returns></returns>
        public override IHttpResult OnAuthenticated(IServiceBase authService,
            IAuthSession session, IAuthTokens tokens,
            Dictionary<string, string> authInfo)
        {
    
            var customUserSession = (Framework.Auth.CustomUserSession) session;
            customUserSession.AuthProvider = "credentials";
            customUserSession.CreatedAt = DateTime.UtcNow;
            customUserSession.UserAuthId = _claims.First(item => item.ClaimName == "sub").ClaimValue;
            customUserSession.FirstName = _claims.First(item => item.ClaimName == "given_name").ClaimValue;
            customUserSession.LastName = _claims.First(item => item.ClaimName == "family_name").ClaimValue;
            customUserSession.Roles = _claims.First(item => item.ClaimName == "product_ids").ClaimValue.Split(",").ToList();
            customUserSession.Permissions = _claims.First(item => item.ClaimName == "product_feature_ids").ClaimValue.Split(",").ToList();
            customUserSession.Email = _claims.First(item => item.ClaimName == "email").ClaimValue;
            customUserSession.Company = _claims.First(item => item.ClaimName == "company_name").ClaimValue;
            customUserSession.ZipCode = _tsoContext.GetUserZip(customUserSession.UserAuthId);
    
            //https://stackoverflow.com/a/47403514/1258525
            //might not need this after correctly implementing IUserSessionSource
            authService.Request.Items[Keywords.DidAuthenticate] = true;
    
            //Call base method to Save Session and fire Auth/Session callbacks:
            return base.OnAuthenticated(authService, session, tokens, authInfo);
        }
    
        public IAuthSession GetUserSession(string userAuthId)
        {
            throw new NotImplementedException();
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   mythz    6 年前

    它应该包含AuthProvider为由标识的已验证用户填充的相同用户会话 userAuthId ,其中在自定义AuthProvider中与 sub 索赔价值。

    您应该创建一个新的UserSession,并尝试重新使用与中使用的相同代码来填充UserSession OnAuthenticated()

    var customUserSession = new Framework.Auth.CustomUserSession();
    customUserSession.AuthProvider = "credentials";
    ...
    

    这个 IUserSessionSource 当前仅在使用RefreshToken请求新的JWT BeareToken时调用,即。

    /access-token?RefreshToken={RefreshToken}
    

    我刚刚添加了一个更改,在更新令牌时 IUserSessionSource 存在于 this commit 因此,如果清除NuGet缓存:

    $ nuget locals all -clear
    

    并从MyGet中恢复ServiceStack V5包。应在成功的身份验证响应中填充RefreshToken,您将能够手动调用:

    /访问令牌?RefreshToken={RefreshToken}
    

    要从RefreshToken中检索新的JWT令牌,该令牌是从返回的UserSession中填充的 GetUserSession() .