ASP.NET MVC 4.7集成Keycloak登录后无限重定向循环问题求助
ASP.NET MVC 4.7 集成Keycloak后登录成功陷入无限重定向循环
我已按如下方式配置ASP.NET MVC 4.7应用,除下述文件外未修改项目初始生成的代码。目前可正常跳转到Keycloak登录页面,但登录成功后重定向到指定的/home路径时,会再次跳转回Keycloak身份服务器,进而陷入无限重定向循环。开发者工具显示Cookie和会话传递正常,尝试过UseKentorOwinCookieSaver、SystemWebCookieManager等网络上的方案均无效,已卡在此问题多日。
相关代码如下:
Startup.cs
using Microsoft.Owin; using Owin; using System; using System.Threading.Tasks; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; using Owin.Security.Keycloak; using Microsoft.Owin.Security.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect; using System.IdentityModel.Tokens; using Microsoft.Owin.Host.SystemWeb; [assembly: OwinStartup(typeof(AspNetMVC4.Startup))] namespace AspNetMVC4 { public class Startup { public void Configuration(IAppBuilder app) { app.UseKentorOwinCookieSaver(); const string persistentAuthType = "keycloak_auth"; app.SetDefaultSignInAsAuthenticationType(persistentAuthType); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = persistentAuthType, AuthenticationMode = AuthenticationMode.Active, CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebCookieManager() }); var desc = new AuthenticationDescription(); desc.AuthenticationType = "keycloak_auth"; desc.Caption = "keycloak_auth"; app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { AuthenticationType = "Auth0", Authority = "http://localhost:8080/auth/realms/master", ClientId = "keycloakdemo", ClientSecret = "tUM2gZiW5H3Lx2DQ4b5t4x5FzzrmADGi", // RedirectUri = "http://localhost:44337/", //PostLogoutRedirectUri = auth0PostLogoutRedirectUri, RedirectUri = "https://localhost:44337/home", ResponseType = OpenIdConnectResponseType.Code, Scope = "openid profile email", CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebCookieManager(), }); } } }
HomeController.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace AspNetMVC4.Controllers { public class HomeController : Controller { [Authorize] public ActionResult Index() { return View(); } public ActionResult About() { bool flag = User.Identity.IsAuthenticated; ViewBag.Message = "Your application description page."; return View(); } public ActionResult Contact() { ViewBag.Message = "Your contact page."; return View(); } } }
问题分析与修复方案
根本原因
- AuthenticationType不匹配:Cookie认证的
AuthenticationType是keycloak_auth,但OpenID Connect的AuthenticationType设为了Auth0,导致登录成功后生成的身份票据无法被Cookie中间件识别,系统判定用户未认证,再次触发跳转。 - RedirectUri指向受保护路径:你把回调地址设为了带
[Authorize]的/home,登录回调时该路径会先触发认证检查,此时身份票据还未完成持久化,直接进入循环。
修复步骤
1. 统一AuthenticationType
将OpenID Connect配置的AuthenticationType改为和Cookie认证一致的keycloak_auth:
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { AuthenticationType = "keycloak_auth", // 与Cookie认证的AuthenticationType保持一致 // 其余配置保留 });
2. 修改RedirectUri为未受保护路径
把回调地址改成应用根路径(或其他无需认证的页面),登录完成后OpenID Connect中间件会自动重定向到用户最初访问的受保护页面:
RedirectUri = "https://localhost:44337/",
同时在Keycloak客户端的Valid Redirect URIs中添加https://localhost:44337/*确保回调合法。
3. 移除无用代码
你创建的AuthenticationDescription实例未被任何中间件使用,直接删除这段冗余代码:
// 以下代码无用,删除 var desc = new AuthenticationDescription(); desc.AuthenticationType = "keycloak_auth"; desc.Caption = "keycloak_auth";
4. 添加认证失败处理(可选)
配置Notifications处理认证失败场景,方便排查问题:
Notifications = new OpenIdConnectAuthenticationNotifications { AuthenticationFailed = n => { n.HandleResponse(); n.Response.Redirect("/Home/About?error=" + Uri.EscapeDataString(n.Exception.Message)); return Task.CompletedTask; } }
修复后的完整Startup.cs代码
using Microsoft.Owin; using Owin; using System; using System.Threading.Tasks; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; using Microsoft.Owin.Security.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.Owin.Host.SystemWeb; [assembly: OwinStartup(typeof(AspNetMVC4.Startup))] namespace AspNetMVC4 { public class Startup { public void Configuration(IAppBuilder app) { app.UseKentorOwinCookieSaver(); const string persistentAuthType = "keycloak_auth"; app.SetDefaultSignInAsAuthenticationType(persistentAuthType); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = persistentAuthType, AuthenticationMode = AuthenticationMode.Active, CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebCookieManager() }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { AuthenticationType = persistentAuthType, Authority = "http://localhost:8080/auth/realms/master", ClientId = "keycloakdemo", ClientSecret = "tUM2gZiW5H3Lx2DQ4b5t4x5FzzrmADGi", RedirectUri = "https://localhost:44337/", PostLogoutRedirectUri = "https://localhost:44337/", ResponseType = OpenIdConnectResponseType.Code, Scope = "openid profile email", CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebCookieManager(), Notifications = new OpenIdConnectAuthenticationNotifications { AuthenticationFailed = n => { n.HandleResponse(); n.Response.Redirect("/Home/About?error=" + Uri.EscapeDataString(n.Exception.Message)); return Task.CompletedTask; } } }); } } }
额外验证项
- 清除浏览器所有Cookie后重新测试,避免旧缓存干扰
- 确认Keycloak客户端的
Access Type设置为confidential(因为你使用了Code流程) - 检查应用的SSL证书是否有效,避免Cookie因
Secure属性无法正常存储
内容的提问来源于stack exchange,提问作者user2300947
相关产品推荐
相关产品推荐

