Identity Server客户端共享具有不同RefreshTokenUsage的刷新令牌

时间:2019-07-13 07:19:46

标签: c# authentication asp.net-core signalr identityserver4

我如何让2个身份服务器客户端共享刷新令牌,但是使用差异RefreshTokenUsage

我们正在尝试将QR码登录流程添加到我们的系统中

假设后端包含3个项目:Identity-Server,API-Server,SignalR-Hub-Server

API-Server从Identity-Server获取Jwt和RefreshToken之后,授权的API端点将负责将RefreshToken发送到SignalR-Hub-Server以获取新的令牌集并发出前端连接登录信号。

问题是我使用API​​登录并使用刷新令牌从集线器获取新令牌后,Identity Server返回错误消息

  

HubServer尝试刷新属于ApiServer的令牌

我们的API服务器具有刷新令牌端点,因此RefreshTokenUsage应该是OneTime 但是,当我们使用该令牌从SignalR-Hub-Server获取新的登录会话时,我们希望刷新而不撤消原始令牌(因为QR登录是要使用现有登录名创建一个新部分),所以我希望RefreshTokenUsage成为ReUse


我目前在Identity-Server项目中拥有什么

API服务器,SignalR-Hub服务器之间的连接已正确设置

Startup.cs

public class Startup
{
    public IConfiguration Configuration { get; }

    public Startup(IConfiguration configuration)
        => Configuration = configuration;

    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddTransient<IIdentityRepository, IdentityRepository>(x => new IdentityRepository(Configuration.GetConnectionString("db")))
            .AddTransient<IRefreshTokenRepository, RefreshTokenRepository>(x => new RefreshTokenRepository(Configuration.GetConnectionString("db")))
            .AddTransient<IAuthenticatorFactory, AuthenticatorFactory>()
            .AddTransient<IRefreshTokenStore, CustomRefreshTokenStore>();

        services
            .AddIdentityServer()
            .AddInMemoryApiResources(InMemoryConfiguration.ApiResources())
            .AddInMemoryClients(InMemoryConfiguration.Clients(Configuration))
            .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>();

        services
            .AddHealthChecks()
            .AddSqlServer(
                Configuration.GetConnectionString("db"),
                name: "db");

        services.AddMvc();
    }

    public void ConfigureContainer(ContainerBuilder builder)
        => builder.RegisterAssemblyTypes(typeof(IAuthenticationProvider).Assembly)
            .Where(t => t.IsAssignableTo<IAuthenticationProvider>())
            .AsImplementedInterfaces();

    public void Configure(IApplicationBuilder app)
        => app.UseIdentityServer();
}

InMemoryConfiguration.cs

public static class InMemoryConfiguration
{
    public static IEnumerable<ApiResource> ApiResources() => new[]
    {
        new ApiResource("ApiServer", "API Server")
        {
            UserClaims = new[]
            {
                JwtRegisteredClaimNames.Jti,
                JwtRegisteredClaimNames.Iat,
                ClaimTypes.Name,
                ClaimTypes.Email
            }
        },
        new ApiResource("HubServer", "SignalR Hub")
        {
            UserClaims = new[]
            {
                JwtRegisteredClaimNames.Jti,
                JwtRegisteredClaimNames.Iat,
                ClaimTypes.Name,
                ClaimTypes.Email
            }
        }
    };

    public static IEnumerable<Client> Clients(IConfiguration configuration) => new[]
    {
        new Client
        {
            ClientId = configuration.GetValue<string>("Client:ApiServer:Id"),
            ClientSecrets =
            {
                new Secret(configuration.GetValue<string>("Client:ApiServer:Secret").Sha256())
            },
            AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
            AllowedScopes =
            {
                IdentityServerConstants.StandardScopes.OfflineAccess,
                configuration.GetValue<string>("Client:ApiServer:Id"),
                configuration.GetValue<string>("Client:HubServer:Id")
            },
            AllowOfflineAccess = true,
            AccessTokenLifetime = configuration.GetValue<int>("JwtLifeTime"),
            RefreshTokenExpiration = TokenExpiration.Absolute,
            AbsoluteRefreshTokenLifetime = configuration.GetValue<int>("RefreshTokenLifeTime"),
        },
        new Client
        {
            ClientId = configuration.GetValue<string>("Client:HubServer:Id"),
            ClientSecrets =
            {
                new Secret(configuration.GetValue<string>("Client:HubServer:Secret").Sha256())
            },
            AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
            AllowedScopes =
            {
                IdentityServerConstants.StandardScopes.OfflineAccess,
                configuration.GetValue<string>("Client:ApiServer:Id"),
                configuration.GetValue<string>("Client:HubServer:Id")
            },
            AllowOfflineAccess = true,
            RefreshTokenUsage = ReUse // <---- This is the only difference between the 2 clients
            AccessTokenLifetime = configuration.GetValue<int>("JwtLifeTime"),
            RefreshTokenExpiration = TokenExpiration.Absolute,
            AbsoluteRefreshTokenLifetime = configuration.GetValue<int>("RefreshTokenLifeTime"),
        }
    };
}

0 个答案:

没有答案