【问题标题】:Identity Server 4 Running Behind a load BalancerIdentity Server 4 在负载均衡器后面运行
【发布时间】:2017-05-11 13:01:40
【问题描述】:

我已经使用实体框架为我的项目设置了 Identity Server 4。我已经将该服务配置为使用持久授权存储和签名证书。

services.AddIdentityServer()
        .AddSigningCredential(Config.GetSigningCertificate())
        .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
        .AddProfileService<ProfileService>()
        .AddConfigurationStore(builder =>
                    builder.UseSqlServer(connectionString, options =>
                        options.MigrationsAssembly(migrationsAssembly)))
        .AddOperationalStore(builder =>
                    builder.UseSqlServer(connectionString, options =>
                        options.MigrationsAssembly(migrationsAssembly)));

这里是服务的配置。

问题是当我在负载均衡器后面运行我的服务器时,例如 2 个处理所有请求的相同实例,用户未登录的服务器无法解码 JWT 令牌,导致 401 未经授权的错误。

我假设令牌的签名方法或其加密是问题,但我找不到解决此问题的方法。

这是我的其余配置。

配置:

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
      Authority = url,
      // Authority = "http://localhost:5000",
      AllowedScopes = { "WebAPI" },
      RequireHttpsMetadata = false,
      AutomaticAuthenticate = true,
      AutomaticChallenge = true,

});

客户:

new Client
{
     ClientId = "Angular2SPA",
     AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, // Resource Owner Password Credential grant.
     AllowAccessTokensViaBrowser = true,
     RequireClientSecret = false, // This client does not need a secret to request tokens from the token endpoint.
     AccessTokenLifetime = 7200, // Lifetime of access token in seconds.
     AllowedScopes = {
                       IdentityServerConstants.StandardScopes.OpenId, // For UserInfo endpoint.
                       IdentityServerConstants.StandardScopes.Profile,
                       "roles",
                       "WebAPI"
                      },
     AllowOfflineAccess = true, // For refresh token.
     AccessTokenType = AccessTokenType.Jwt

}

我还实现了自己的 IResourceOwnerPasswordValidator 和 IProfileService。

知道为什么会这样吗?

【问题讨论】:

  • 在过去,您必须确保网络花园中的所有机器(天哪,太旧了)都必须具有相同的机器密钥或类似的机器密钥。这里可能有类似的问题。不知道他们用什么来加密,但不管它是什么,它在所有身份服务器机器上都必须是相同的。
  • 问题是.AddSigningCredential(Config.GetSigningCertificate()) 从我的存储中获取证书,并且在每台机器上都是一样的。因此它能够解密存储在 db 中的 refresh_tokens,但不能解密 JWT 令牌。
  • 似乎这不是负责签署 JWT 令牌的原因。问题是,究竟是什么?
  • 是的,我也是这么想的,但是我找不到修改用于加密或签署令牌的证书或密钥的方法。 :/ 知道这是在哪里设置的吗?
  • 我将开始阅读代码github.com/aspnet/Security/tree/master/src/… 看起来您可以潜入 JwtBearerOptions 并控制如何通过 ISecurityTokenValidator(SecurityTokenValidators 属性)对其进行验证。这个博客有很多信息,看起来andrewlock.net/…我从来没有用Core做过任何这些事情,所以我没有更多的帮助。祝你好运!

标签: c# .net asp.net-core asp.net-identity


【解决方案1】:

我有一个类似的问题,负载平衡 Identity Server 4 并且能够使用 Startup.cs 的 ConfigureServices 中的 .AddDataProtection() 共享密钥。

public void ConfigureServices(IServiceCollection services)
{
// Other service configurations

  services.AddDataProtection();

// Additional service configurations    
}

附带说明一下,如果您选择这条路线,请考虑使用类似的扩展名加密这些密钥(在您决定使用的任何介质中) .ProtectKeysWith*(有几种选择) .更多信息请见https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/introduction?view=aspnetcore-2.1

HTH

【讨论】:

    猜你喜欢
    • 2021-01-03
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-25
    相关资源
    最近更新 更多