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

ASP.NET Core 6集成Keycloak登录成功后认证失败问题排查

问题:ASP.NET Core MVC集成Keycloak登录后无法识别认证状态

我用Docker部署了本地Keycloak服务器,创建了Realm、用户、角色及客户端(仅设置凭据获取密钥,未配置映射器、客户端范围等),其他语言(PHP/Node.js)应用用类似配置可正常工作。但在ASP.NET Core MVC项目中,访问需要授权的页面触发Keycloak登录,登录成功跳转后User.Identity.IsAuthenticated始终为false,系统无法识别已认证状态。

相关配置代码如下:

认证中间件配置

services.AddAuthentication(options =>
{
    //Sets cookie authentication scheme
    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(cookie =>
{
    //Sets the cookie name and maxage, so the cookie is invalidated.
    cookie.Cookie.Name = "keycloak.cookie";
    cookie.Cookie.MaxAge = TimeSpan.FromMinutes(60);
    cookie.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
    cookie.SlidingExpiration = true;
})
.AddOpenIdConnect(options =>
{
    //Use default signin scheme
    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    //Keycloak server
    options.Authority = Configuration.GetSection("Keycloak")["ServerRealm"];
    //Keycloak client ID
    options.ClientId = Configuration.GetSection("Keycloak")["ClientId"];
    //Keycloak client secret
    options.ClientSecret = Configuration.GetSection("Keycloak")["ClientSecret"];

    //Keycloak .wellknown config origin to fetch config
    // options.MetadataAddress = Configuration.GetSection("Keycloak")["Metadata"];
    //Require keycloak to use SSL
    options.RequireHttpsMetadata = false;
    options.GetClaimsFromUserInfoEndpoint = true;
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("email");

    //Save the token
    options.SaveTokens = true;
    //Token response type, will sometimes need to be changed to IdToken, depending on config.
    options.ResponseType = OpenIdConnectResponseType.Code;
    //SameSite is needed for Chrome/Firefox, as they will give http error 500 back, if not set to unspecified.
    options.NonceCookie.SameSite = SameSiteMode.None;
    options.CorrelationCookie.SameSite = SameSiteMode.None;
    
    options.TokenValidationParameters = new TokenValidationParameters
    {
        NameClaimType = "name",
        RoleClaimType = "https://schemas.scopic.com/roles"
    };

    Configuration.Bind("<Json Config Filter>", options);
    options.Events.OnRedirectToIdentityProvider = async context =>
    {
        context.ProtocolMessage.RedirectUri = "http://localhost:13636/home";
        await Task.FromResult(0);
    };

});

中间件顺序配置

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

HomeController代码

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
    }

    public IActionResult Index()
    {
        bool value = User.Identity.IsAuthenticated;
        return View();
    }

    [Authorize]
    public IActionResult Privacy()
    {
        return View();
    }
}

修复方案

1. 修正OIDC回调地址逻辑

移除OnRedirectToIdentityProvider事件中硬编码的RedirectUri:

// 删除这段代码
// options.Events.OnRedirectToIdentityProvider = async context =>
// {
//     context.ProtocolMessage.RedirectUri = "http://localhost:13636/home";
//     await Task.FromResult(0);
// };

OIDC中间件默认使用/signin-oidc作为回调端点,这个路径是中间件内置处理认证响应、生成认证Cookie的核心路径。硬编码其他地址会导致Keycloak回调后无法触发认证流程的收尾逻辑。

同时在Keycloak客户端的Valid Redirect URIs中添加http://localhost:13636/signin-oidc,确保Keycloak允许回调到该地址。

2. 修复Configuration.Bind占位符

将Configuration.Bind("<Json Config Filter>", options);中的<Json Config Filter>替换为实际的配置节点名称(例如"Keycloak:Oidc",对应appsettings.json中的配置结构),如果没有额外的JSON配置,直接删除该行代码,避免覆盖之前的正确配置。

3. 匹配Keycloak角色声明类型

Keycloak默认的角色声明路径是realm_access.roles,如果未在Keycloak中配置自定义映射,需要修改TokenValidationParameters:

options.TokenValidationParameters = new TokenValidationParameters
{
    NameClaimType = "name",
    RoleClaimType = "realm_access.roles" // 改为Keycloak默认的角色声明路径
};

若要保留自定义RoleClaimType,需在Keycloak客户端添加映射器,将realm_access.roles映射到https://schemas.scopic.com/roles。

4. 完善中间件路由配置

确保控制器路由配置在UseAuthorization之后,保证认证授权逻辑先于路由执行:

app.UseAuthentication();
app.UseAuthorization();

// 添加控制器路由配置
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

5. 检查Keycloak客户端基础配置

  • 确认客户端Access Type设置为confidential(因为使用了ClientSecret)
  • 确保Valid Redirect URIs包含http://localhost:13636/*或具体的回调/跳转地址
  • 验证Standard Flow Enabled已启用(对应Code响应类型的授权流程)

修改完成后重启ASP.NET Core应用,再次测试登录流程,User.Identity.IsAuthenticated即可正确识别认证状态。

内容的提问来源于stack exchange,提问作者James Bond

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:05:23