如何正确实现IUserSessionSource - ServiceStack

时间:2017-11-22 18:26:50

标签: c# servicestack

ServiceStack 5.0添加了一项新功能,允许在没有IAuthRepositorysee here

的情况下使用refreshTokens

我不知道有任何可用于ServiceStack 5.0新功能的文档,我有一个自定义AuthProvider,我不知道如何实现IUserSessionSource

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

这是我的代码:

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 个答案:

答案 0 :(得分:2)

它应包含您的AuthProvider为userAuthId标识的经过身份验证的用户填充的相同UserSession,该用户会在您的自定义AuthProvider中与sub声明值匹配。

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

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

目前仅在使用RefreshToken请求新的JWT BearerToken时调用IUserSessionSource,即

/access-token?RefreshToken={RefreshToken}

我刚刚添加了一个更改,当this commit中存在IUserSessionSource时,正在填充RefreshTokens,所以如果你清除你的NuGet缓存:

$ nuget locals all -clear

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

/access-token?RefreshToken={RefreshToken}

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