C# 在signin oidc重定向时关联失败
当托管在NGINX负载平衡器后面的虚拟机上时,尝试验证.NET Core 3.1 web应用程序时,我遇到了以下问题(在本地,它按预期工作,当前负载平衡器中只有一个VM): 异常:关联失败。未知位置 异常:处理远程登录时遇到错误。 Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandlerRequestAsync() 我做了很多研究,尝试了十几种修复方法,但似乎都不起作用。以下是我的代码片段: Startup.Configure() 最后,我做了一些尝试:C# 在signin oidc重定向时关联失败,c#,oauth,correlation,asp.net-core-3.1,C#,Oauth,Correlation,Asp.net Core 3.1,当托管在NGINX负载平衡器后面的虚拟机上时,尝试验证.NET Core 3.1 web应用程序时,我遇到了以下问题(在本地,它按预期工作,当前负载平衡器中只有一个VM): 异常:关联失败。未知位置 异常:处理远程登录时遇到错误。 Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandlerRequestAsync() 我做了很多研究,尝试了十几种修复方法,但似乎都不起作用。以下是我的代码片段: Startup.C
services.Configure(选项=>
{
options.ForwardedHeaders=
ForwardedHeaders.XForwardedFor|
ForwardedHeaders.XForwardedHost|
ForwardedHeaders.XForwardedProto;
options.ForwardLimit=2;//限制受信任的代理跃点数
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
及
app.UseHttpsRedirection()
及
CookiePolicyOptions cookiePolicy=新CookiePolicyOptions()
{
安全=烹饪安全政策。始终,
};
及
redirectContext.ProtocolMessage.State=
options.StateDataFormat.Protect(redirectContext.Properties)
及
应用程序使用((上下文,下一步)=>
{
context.Request.Scheme=“https”;
返回next();
});
更新:
在使用OP进行一些测试之后,似乎由于大小的原因,身份验证cookie被NGINX阻止。通过更改NGINX配置解决了此问题:
请检查您是否能够在dev中运行下面的配置?测试前 在NGINX后面的实例中,确保已向OpenId连接提供程序注册该URL 还要检查X-Forwarded-For和X-Forwarded-Proto是否已传递到您的应用程序。在服务器更改之后,我就遇到过几次这样的问题 我建议用一个干净的应用程序来测试这一点,作为概念证明(POC)。当POC启动并在所有环境中运行时,您可以将更改应用于现有代码库 在Startup.ConfigureServices中
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
var forwardedHeaderOptions = new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
};
forwardedHeaderOptions.KnownNetworks.Clear();
forwardedHeaderOptions.KnownProxies.Clear();
app.UseForwardedHeaders(forwardedHeaderOptions);
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseSession();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
var openIdConnectSettings = new OpenIdConnectSettings();
Configuration.GetSection("OpenIdConnect").Bind(openIdConnectSettings);
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.Authority = openIdConnectSettings.Authority;
options.ClientId = openIdConnectSettings.ClientId;
options.ClientSecret = openIdConnectSettings.ClientSecret;
options.ResponseType = OpenIdConnectResponseType.Code;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("openid");
options.SaveTokens = true;
});
在启动中。配置
// Initialize the ping options and get default values from the config
var pingOptions = Configuration.GetSection("PingOAuthWebOptions").Get<PingOAuthWebOptions>();
// Testing Stack OVerflow Example
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "oidc";
})
.AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(10000);
options.Cookie.Name = "PINGSESSION";
})
.AddOpenIdConnect("oidc", options =>
{
options.Authority = pingOptions.Authority;
options.ClientId = pingOptions.ClientId;
options.ClientSecret = pingOptions.ClientSecret;
options.ResponseType = OpenIdConnectResponseType.Code;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("openid"); // Added this
options.SaveTokens = true;
options.Events = new OpenIdConnectEvents()
{
OnRedirectToIdentityProvider = async ctx =>
{
// Change from "HTTP" to "HTTPS" if requested and necessary
if (pingOptions.ForceSecureRedirect && ctx.ProtocolMessage.RedirectUri.StartsWith("http:"))
{
ctx.ProtocolMessage.RedirectUri = ctx.ProtocolMessage.RedirectUri.Replace("http:", "https:");
}
await Task.FromResult(0);
},
OnUserInformationReceived = ctx =>
{
var accessToken = ctx.ProtocolMessage.AccessToken;
var jwt = new JwtSecurityTokenHandler().ReadJwtToken(accessToken);
var appIdentity = new ClaimsIdentity(jwt.Claims);
// Add app role
appIdentity.AddClaim(new Claim(ClaimTypes.Role, "Superuser"));
ctx.Principal.AddIdentity(appIdentity);
return Task.CompletedTask;
},
};
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseCookiePolicy();
}
else
{
app.UseStatusCodePagesWithReExecute( ...
// required in order to get https for OpenIdConnect
// must come before app.UseAuthentication();
var forwardedHeaderOptions = new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
};
forwardedHeaderOptions.KnownNetworks.Clear();
forwardedHeaderOptions.KnownProxies.Clear();
app.UseForwardedHeaders(forwardedHeaderOptions);
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
....
配置类
public class OpenIdConnectSettings
{
public string Authority { get; set; }
public string ClientId { get; set; }
public string ClientSecret { get; set; }
}
感谢Roar的及时回复。我已验证URL是否已向OpenId连接提供程序注册(我在负载平衡器后面使用Http时遇到问题,并且在某一点上存在不匹配错误。我已将此问题的修复程序放入Auth Library应用程序中。不确定这是否会导致问题??)我已经尽可能地清理了代码,并删除了对库的引用。同样,它在本地工作,但在NGINX.Hi Troy后面托管时不起作用。在LB(LB和您的应用程序之间的http)中,SSL终端应该可以正常工作。我认为在您的应用程序中使用http for OpenId Connect端点时,一切都不起作用。我没有env来验证后者,很抱歉。所以我不完全确定你在我的应用程序中对OpenId连接端点的意思:因为我们的证书位于LB上,所以我不得不添加一行:“ctx.ProtocolMessage.RedirectUri=ctx.ProtocolMessage.RedirectUri.Replace”(“http:,“https:”);”你是说你认为那行不通吗?所有其他端点都在使用HTTPS。我还注意到事件查看器中存在以下问题:无法确定重定向的HTTPS端口。“。未找到AspNetCore.Correlation.oidc.xxxxxxx“”cookie。我正在引用/登录oicd端点。如果您在OpenId连接提供程序中使用http指定此选项,并且在LB中使用https重定向,那么事情将失败。溴
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseCookiePolicy();
}
else
{
app.UseStatusCodePagesWithReExecute( ...
// required in order to get https for OpenIdConnect
// must come before app.UseAuthentication();
var forwardedHeaderOptions = new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
};
forwardedHeaderOptions.KnownNetworks.Clear();
forwardedHeaderOptions.KnownProxies.Clear();
app.UseForwardedHeaders(forwardedHeaderOptions);
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
....
public class OpenIdConnectSettings
{
public string Authority { get; set; }
public string ClientId { get; set; }
public string ClientSecret { get; set; }
}