You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();
        }
    }
}

问题分析与修复方案

根本原因

  1. AuthenticationType不匹配:Cookie认证的AuthenticationType是keycloak_auth,但OpenID Connect的AuthenticationType设为了Auth0,导致登录成功后生成的身份票据无法被Cookie中间件识别,系统判定用户未认证,再次触发跳转。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 13:50:34