.NET Core集成OpenID认证时出现登录重定向无限循环问题
.NET Core OpenID认证重定向循环问题排查与解决
问题描述
在.NET Core应用中集成OpenID认证时,输入登录凭据后陷入应用与认证服务器之间的持续重定向循环,最终收到错误提示:"We couldn't sign you in. Please try again."
当前配置代码
Startup.cs中的认证服务配置
services.AddHttpContextAccessor(); services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme) .AddOpenIdConnect(options => { options.ClientId = ""; options.Authority = ""; options.Scope.Clear(); options.Scope.Add("openid"); options.Scope.Add("profile"); options.ResponseType = OpenIdConnectResponseType.IdToken; options.GetClaimsFromUserInfoEndpoint = true; options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.UseTokenLifetime = false; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true }; options.SaveTokens = true; options.Events = new OpenIdConnectEvents { OnRedirectToIdentityProvider = async (context) => { context.ProtocolMessage.RedirectUri = ""; context.ProtocolMessage.PostLogoutRedirectUri = ""; await Task.CompletedTask; }, OnTokenValidated = context => { return Task.CompletedTask; }, OnAuthorizationCodeReceived = (context) => { Console.WriteLine("Token Received: " + context.TokenEndpointResponse.IdToken); return Task.CompletedTask; }, OnAuthenticationFailed = OnAuthenticationFailed }; });
中间件调用顺序
已确认顺序正确:
app.UseAuthentication(); app.UseAuthorization();
自定义中间件尝试
移除上述中间件,仅依赖[Authorize]标签时问题仍存在,自定义中间代码如下:
app.Use(async (context, next) => { var user = context.User; if (user == null || user.Identity == null || !user.Identity.IsAuthenticated) { await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { IsPersistent = false, RedirectUri = "" }); return; } await next(); });
解决方法
1. 修复空RedirectUri配置
在OnRedirectToIdentityProvider事件中,你将RedirectUri设为空字符串,导致认证服务器无法正确回调到应用,认证成功后无法生成有效认证Cookie,应用持续发起认证挑战。
- 解决:删除事件中对
RedirectUri的硬编码,或设置正确的回调地址(默认回调路径为/signin-oidc):
OnRedirectToIdentityProvider = async (context) => { // 注释掉空赋值,使用默认配置 // context.ProtocolMessage.RedirectUri = ""; context.ProtocolMessage.PostLogoutRedirectUri = "你的登出回调地址"; await Task.CompletedTask; }
也可以直接在OpenIdConnectOptions中配置CallbackPath:
options.CallbackPath = "/signin-oidc";
2. 匹配ResponseType与认证流程
当前设置ResponseType = OpenIdConnectResponseType.IdToken(Implicit流程),但同时开启了GetClaimsFromUserInfoEndpoint = true,该配置需要Authorization Code流程支持。
- 解决:将ResponseType改为
CodeIdToken以兼容用户信息端点调用:
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
3. 检查TokenValidationParameters配置
ValidateIssuer = true时,必须确保Authority地址与认证服务器返回的Issuer完全匹配,否则会导致Token验证失败,无法完成认证。
- 解决:确认
Authority地址正确;若为开发环境可临时设置ValidateIssuer = false排查问题:
options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false // 开发环境临时关闭,生产环境需开启并确保Authority正确 };
4. 完善Cookie认证配置
当前AddCookie未配置Cookie的核心属性(如SameSite、Secure等),在部分环境下可能导致认证Cookie无法正常保存。
- 解决:添加Cookie基础配置:
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => { options.Cookie.SameSite = SameSiteMode.Lax; options.Cookie.SecurePolicy = CookieSecurePolicy.None; // 开发环境用None,生产环境改为Always options.Cookie.HttpOnly = true; })
5. 修复自定义中间件的空RedirectUri
自定义中间件中ChallengeAsync的RedirectUri为空,导致认证成功后无法跳回原请求页面,再次触发认证挑战。
- 解决:设置
RedirectUri为当前请求路径:
await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { IsPersistent = false, RedirectUri = context.Request.Path.Value });
内容的提问来源于stack exchange,提问作者satya00
相关产品推荐
相关产品推荐

