【问题标题】:Authenticate Angular Application to Web Api with Existing SSO using Ping Federate使用 Ping Federate 使用现有 SSO 向 Web Api 验证 Angular 应用程序
【发布时间】:2025-12-18 10:20:05
【问题描述】:

我们有一个现有的 SSO 应用程序,其登录表单用于验证 ping federate。

我正在尝试在 angular cli 11 中使用相同的 SSO 机制。

我已经到了从 Pingfederate 返回开放令牌的地步。我想要做的不是我们设置我的 ASP.NET 核心应用程序来接受这个令牌,验证它,并授予我访问其中的声明的权限。

在较旧的 MVC 应用程序中,此令牌是使用类似于密码的 opentoken 库解密的。

如何配置我的 .net core 3.1 应用程序以接受和验证这个开放令牌?

这是我目前所拥有的:

services.AddAuthentication()
            .AddOAuth("urn:ietf:params:oauth:grant-type:saml2-bearer", opt =>
            {
                opt.ClientId = Configuration["PingOpenToken:ClientId"];
                opt.ClientSecret = Configuration["PingOpenToken:ClientSecret"];
            });

其中客户端密码与我们用来解密令牌的密码相同。我不知道 Client Id 值应该是什么。

urn:ietf:params:oauth:grant-type:saml2-bearer 来自This ping documentation

我假设我要将授权标头中的开放令牌放置为bearer {token}

为了验证我的 pingfederate 配置并查看是否需要打开其他任何东西,在我的协议设置下,我有:

  • 启用 OAuth 2.0 授权服务器:false
  • IdP SAML 2.0 支持:true
  • SP SAML 2.0 支持:true

如果我需要开启 oAuth 2.0,我不知道如何配置它。

【问题讨论】:

  • 您必须使用 OpenToken 适配器吗?或者,您可以与您的 PF 管理员一起使用无代理适配器吗?无代理更容易,浏览器为您提供参考,您的应用程序将该参考和应用程序的秘密发送给 PF,然后您将返回属性映射的 JSON... 方式更简单,并且将来不太可能被中断。
  • 不幸的是,之前的管理员被解雇了,所以我不得不自己解决这个问题。所有较旧的站点都通过我们的 SSO 应用程序使用这种开放令牌方法,而且我们的 PF 版本似乎已经足够老了,我们唯一的产品就是开放令牌。我们有一些似乎是 PF 多年前编写的用于读写令牌的库,但它是用 4.0 编写的,与核心不兼容。

标签: asp.net-core-webapi asp.net-core-3.1 pingfederate


【解决方案1】:

在与 PingFederate 的几个人通话后,我想出了如何配置和使用 PF oauth,而不是使用他们的 opentoken 实现。

要点是用户被发送到 SSO,当他们回到我的 Angular 应用程序时,他们点击了一个带有令牌的 url。然后,我使用令牌对 PF 进行 API 调用,以获取他们的 oauth 令牌。

然后在我的 API 中,我有一个 azure 广告服务主体和 PF 的双重配置,如下所示:

services.AddAuthentication()
            .AddJwtBearer(ApiConstants.AuthenticationSchemes.AzureBearerToken, opt =>
            {
                opt.Audience = Configuration["AzureAd:ResourceId"];
                opt.Authority = $"{Configuration["AzureAd:Instance"]}{Configuration["AzureAd:TenantId"]}";
                opt.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = false
                };
            })
            .AddJwtBearer(ApiConstants.AuthenticationSchemes.PingBearerToken, opt =>
            {
                opt.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = Configuration["PingFederate:JwtIssuer"],
                    ValidAudience = Configuration["PingFederate:JwtAudience"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["PingFederate:JwtSymmetricKey"]))
                };
            });

        services.AddAuthorization(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .AddAuthenticationSchemes(ApiConstants.AuthenticationSchemes.PingBearerToken, 
                    ApiConstants.AuthenticationSchemes.AzureBearerToken)
                .Build();
        });

我的两个常量值是“azure”和“ping”。

【讨论】: