servicestack,C#,servicestack" /> servicestack,C#,servicestack" />

C# 如何正确实现IUserSessionSource-ServiceStack

C# 如何正确实现IUserSessionSource-ServiceStack,c#,servicestack,C#,servicestack,添加了一项新功能,允许在不使用IAuthRepository的情况下刷新令牌 我不知道ServiceStack 5.0的这一新功能有任何可用文档,我有一个自定义的AuthProvider,我不知道如何实现IUserSessionSource 目前,我的IUserSessionSource.GetUserSession实现甚至没有被调用,我已经清除了Nuget缓存,并从ServiceStacks Nuget服务器检索到了最新的5.0 libs 这是我的密码: public class Custom

添加了一项新功能,允许在不使用
IAuthRepository
的情况下刷新令牌

我不知道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();
    }
}
公共类CustomCredentialAuthProvider:CredentialAuthProvider,IUserSessionSource { 私有只读itscontext(u tsoContext); 私人IEnumerable_索赔; 公共CustomCredentialAuthProvider(ITsoContext tsoContext) { _tsoContext=tsoContext; } 公共覆盖布尔TryAuthenticate(IServiceBase authService, 字符串用户名、字符串密码) { _声明=_tsoContext.AuthenticateUser(用户名、密码); return _claims.Any(); } /// ///参考:https://github.com/ServiceStack/ServiceStack/blob/a5bc5f5a96fb990b69dcad9dd5e95e688477fd94/src/ServiceStack/Auth/CredentialsAuthProvider.cs#L236 ///参考:https://stackoverflow.com/questions/47403428/refreshtoken-undefined-after-successful-authentication-servicestack/47403514#47403514 /// /// /// /// /// /// 公共覆盖IHTTPRESSLT OnAuthenticated(IServiceBase authService, IAuthSession会话,IAuthTokens令牌, 字典(authInfo) { var customUserSession=(Framework.Auth.customUserSession)会话; customUserSession.AuthProvider=“凭证”; customUserSession.CreatedAt=DateTime.UtcNow; customUserSession.UserAuthId=\u claims.First(item=>item.ClaimName==“sub”).ClaimValue; customUserSession.FirstName=\u claims.First(item=>item.ClaimName==“给定的名称”).ClaimValue; customUserSession.LastName=\u claims.First(item=>item.ClaimName==“family\u name”).ClaimValue; customUserSession.Roles=\u claims.First(item=>item.ClaimName==“product\u ID”).ClaimValue.Split(“,”).ToList(); customUserSession.Permissions=\u claims.First(item=>item.ClaimName==“product\u feature\u ID”).ClaimValue.Split(“,”).ToList(); customUserSession.Email=\u claims.First(item=>item.ClaimName==“Email”).ClaimValue; customUserSession.Company=\u claims.First(item=>item.ClaimName==“Company\u name”).ClaimValue; customUserSession.ZipCode=\u tsoContext.GetUserZip(customUserSession.UserAuthId); //https://stackoverflow.com/a/47403514/1258525 //正确实现IUserSessionSource后可能不需要此选项 authService.Request.Items[Keywords.DidAuthenticate]=true; //调用基本方法保存会话并触发身份验证/会话回调: 返回base.OnAuthenticated(authService、会话、令牌、authInfo); } 公共IAuthSession GetUserSession(字符串userAuthId) { 抛出新的NotImplementedException(); } }
它应该包含AuthProvider为由
userAuthId
标识的身份验证用户填充的相同用户会话,该用户会话在自定义AuthProvider中与
sub
声明值匹配

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

当前仅当使用RefreshToken请求新的JWT BealerToken时才会调用
IUserSessionSource
,即

/access-token?RefreshToken={RefreshToken}
我刚刚添加了一个更改,当中存在
IUserSessionSource
时,将填充刷新令牌,因此如果清除NuGet缓存:

$ nuget locals all -clear
并从MyGet还原ServiceStack V5包。在成功的身份验证响应中,应填充RefreshToken,并且您将能够手动调用:

/access-token?RefreshToken={RefreshToken}
从RefreshToken中检索新的JWT令牌,该令牌是从
GetUserSession()
返回的UserSession中填充的

/access-token?RefreshToken={RefreshToken}