2017-05-22 69 views
1

我在負載平衡器後面的IdentityServer存在問題,
爲了清楚我是否使用直接ips,evertything按預期工作。負載平衡器「令牌端點的HTTP請求無效」

目前我在LB上有一個SSL配置,使用一個有效的證書重定向到2臺Linux機器上託管的HTTP碼頭引擎。

我使用我的客戶端的MVC混合流量:

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions 
{ 
    AuthenticationScheme = "oidc", 
    SignInScheme = "Cookies", 
    Authority = settings.Server, 
    RequireHttpsMetadata = "false", 
    ClientId = "MyMvcClient", 
    ClientSecret = "MyMvcSuperPassword", 
    ResponseType = "code id_token", 
    GetClaimsFromUserInfoEndpoint = true, 
    SaveTokens = true, 
    TokenValidationParameters = new TokenValidationParameters 
    { 
     NameClaimType = JwtClaimTypes.Name, 
     RoleClaimType = JwtClaimTypes.Role, 
    }, 
    Events = new OpenIdConnectEvents() 
    { 
     OnRemoteFailure = context => 
     { 
      context.Response.Redirect("/error"); 
      context.HandleResponse(); 
      return Task.FromResult(0); 
     } 
    }, 
    "Scope": { "openid", "profile", "email", "myclient", "offline_access" } 
}); 

在服務器端,我有以下設置:

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddDbContext<IdentityDbContext>(builder); 
    services.AddIdentity<ApplicationUser, ApplicationRole>() 
     .AddEntityFrameworkStores<IdentityDbContext, Guid>() 
     .AddUserStore<UserStore<ApplicationUser, ApplicationRole, IdentityDbContext, Guid>>() 
     .AddRoleStore<RoleStore<ApplicationRole, IdentityDbContext, Guid>>() 
     .AddUserManager<LdapUserManager>() 
     .AddSignInManager<LdapSignInManager>() 
     .AddDefaultTokenProviders() 
     .AddIdentityServerUserClaimsPrincipalFactory(); 
    ... 
    string redisSettings = $"{redisHost}:{redisPort},ssl={redisSsl},abortConnect={redisAbortConnect},password={redisPassword}"; 
    services.AddDataProtection().PersistKeysToRedis(redis, redisKey); 
    ... 
    // Adds IdentityServer 
    services.AddIdentityServer() 
     .AddSigningCredential(new X509Certificate2("IdentityServerAuth.pfx")) 
     .AddConfigurationStore(builder) 
     .AddOperationalStore(builder) 
     .AddAspNetIdentity<ApplicationUser>() 
     .AddProfileService<IdentityProfileService>(); 
} 
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider) 
{ 
    app.UseIdentity(); 
    app.UseForwardedHeaders(new ForwardedHeadersOptions 
    { 
     ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto 
    }); 
    // Adds IdentityServer 
    app.UseIdentityServer(); 
} 

正如我已經提到的,它適用於配置沒有負載均衡器,但客戶端失敗,錯誤爲 「消息包含錯誤:'invalid_request',error_description:'error_description爲空',error_uri:'error_uri爲空'。」

和服務器端我收到 信息:IdentityServer4.Hosting.IdentityServerMiddleware [0] 調用IdentityServer端點:IdentityServer4.Endpoints.TokenEndpoint用於/連接/令牌 警告:IdentityServer4.Endpoints.TokenEndpoint [0] 令牌端點的HTTP請求無效

+0

你啓用[向前頭(HTTPS: //docs.microsoft.com/en-us/aspnet/core/publishing/linuxproduction#configure-a-reverse-proxy-server)? SSL在代理處終止,Identity/WebApi在大多數情況下都需要SSL(因爲JWT令牌在http上並不安全) – Tseng

+0

如果通過啓用轉發標頭,您的意思是 'app.UseForForwardedHeaders(new ForwardedHeadersOptions {ForwardedHeaders = ForwardedHeaders .XForwardedFor | ForwardedHeaders.XForwardedProto });' Then Yes – Artem

回答

0

我已經解決了這個問題。 該解決方案發現跟蹤Request.HttpContext.Connection.RemoteIpAddress 它是無效的,並且等於負載平衡器的IP。因此,解決方案是使用以下方式添加Ip:

options.KnownProxies.Clear(); 
options.KnownProxies.Add(IPAddress.Parse("LoadBalancer IP")); 
app.UseForwardedHeaders(options); 

或通過掩碼192.168.1.0/8:

options.KnownNetworks.Clear(); 
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("192.168.1.0"), 8)); 
app.UseForwardedHeaders(options); 

在這種情況下客戶端的IP地址將被傳遞到Identity Server和您將不會收到異常:

Invalid HTTP request for token endpoint