本文介绍了如何正确实现 IUserSessionSource - ServiceStack的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

一项新功能已添加到 ServiceStack 5.0 允许在没有 IAuthRepository 的情况下使用 refreshTokens,参见此处

A new feature has been added to ServiceStack 5.0 that allows for refreshTokens without an IAuthRepository, see here

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

I do not know of any documentation available for this new feature of ServiceStack 5.0, I have a Custom AuthProvider and I am not sure how to implement IUserSessionSource.

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

Currently, my IUserSessionSource.GetUserSession implementation is not even called and I have cleared my Nuget cache and retrieved the latest 5.0 libs from ServiceStacks Nuget server.

这是我的代码:

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();
    }
}

推荐答案

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

It should contain the same UserSession that your AuthProvider populates for an Authenticated User identified by userAuthId, which in your Custom AuthProvider matches the sub Claim Value.

您应该创建一个新的 UserSession 并尝试重新使用与 OnAuthenticated()

You should create a new UserSession and try re-use the same code to populate the UserSession as being used in OnAuthenticated()

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

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

The IUserSessionSource is currently only invoked when using the RefreshToken to request a new JWT BearerToken, i.e.

/access-token?RefreshToken={RefreshToken}

我刚刚添加了一个更改,当 IUserSessionSource 存在于 这个提交 所以如果你清除你的 NuGet 缓存:

I've just added a change where RefreshTokens are being populated when IUserSessionSource exists in this commit so if you clear your NuGet cache:

$ nuget locals all -clear

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

And restore the ServiceStack V5 packages from MyGet the RefreshToken should be populated on a successful Authentication Response and you will be able to manually call:

/access-token?RefreshToken={RefreshToken}

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

To retrieve a new JWT Token from your RefreshToken which is populated from the UserSession returned from GetUserSession().

这篇关于如何正确实现 IUserSessionSource - ServiceStack的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 19:41