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

ASP.NET Core 2.0集成Ping Federate JWT认证无法跳转登录页问题

问题分析与解决方案

你遇到的核心问题是用错了认证方案:JwtBearer 是为无状态API场景设计的,它只会在未认证时返回401 Unauthorized,不会自动跳转到第三方登录页;而你的MVC Web应用需要基于会话的认证,应该结合Cookie认证和**OpenID Connect (OIDC)**来对接Ping Federate,这样才能触发跳转登录的逻辑。

具体修改步骤

1. 替换认证服务配置

把原来的AddJwtBearer替换为Cookie认证+OpenID Connect的组合,这才是MVC Web应用对接OAuth2/OpenID提供商的正确方式:

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;

// ... 保留原有using引用

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    // 配置Cookie认证,用于存储用户会话
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {
            options.LoginPath = "/Account/Login"; // 作为 fallback,实际会被OIDC逻辑覆盖
            options.AccessDeniedPath = "/Account/AccessDenied";
        })
        .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
        {
            // Ping Federate核心配置
            options.Authority = "https://companyname.com"; // Ping Federate根地址
            options.ClientId = "CompanyName.Web.JWTAuthExample"; // 你的客户端ID
            options.RedirectUri = "https://JWTAuthExample/Account/Login"; // 回调地址,需与Ping Federate后台配置一致
            options.ResponseType = "code"; // 和你提供的登录链接的response_type保持一致
            options.Scope.Clear();
            // 若需要获取用户基本信息,可添加:options.Scope.Add("openid");

            // 用X509证书验证Token
            options.TokenValidationParameters = new TokenValidationParameters
            {
                RequireExpirationTime = true,
                ValidateLifetime = true,
                ValidateAudience = false, // 可根据业务需求开启并配置正确Audience
                ValidIssuer = "https://companyname.com", // 需与Token中的iss字段一致
                RequireSignedTokens = true,
                IssuerSigningKey = KEY // 你之前加载的X509SecurityKey
            };

            // 可选:自定义事件处理
            options.Events = new OpenIdConnectEvents
            {
                OnAuthenticationFailed = context =>
                {
                    context.Response.Redirect("/Home/Error");
                    context.HandleResponse();
                    return Task.CompletedTask;
                },
                OnAuthorizationCodeReceived = context =>
                {
                    // 可在此处处理授权码,比如获取AccessToken等操作
                    return Task.CompletedTask;
                }
            };
        });

    // 调整授权策略,使用Cookie认证的Scheme(会话存储在Cookie中)
    services.AddAuthorization(options =>
    {
        options.AddPolicy("Mvc", policy =>
        {
            policy.AuthenticationSchemes.Add(CookieAuthenticationDefaults.AuthenticationScheme);
            policy.RequireAuthenticatedUser();
        });
    });
}

2. 确认中间件顺序

你的Configure方法里的中间件顺序是正确的,确保UseAuthentication在UseMvc之前即可:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseStaticFiles();
    app.UseAuthentication(); // 必须在UseMvc之前执行
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

为什么之前的方案不工作?

  • JwtBearer中间件的设计目标是无状态API:当用户未认证时,它只会返回401响应,不会触发跳转登录页的逻辑,所以你的OnChallenge事件根本不会被触发。
  • 而OpenID Connect中间件专门用于对接第三方身份提供商(比如Ping Federate),它会在用户未认证时自动跳转到你指定的授权端点(也就是你给出的https://companyname.com/authorization.oauth2),完成认证后回调到你的应用,并用Cookie存储用户会话。

额外注意事项

  • 确保Ping Federate后台已正确配置你的客户端ID、回调地址(RedirectUri),并且允许code类型的响应。
  • 若需要获取用户的Claims信息,可在OnTokenValidated事件中处理,或直接在Controller里通过User.Claims访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:08:46