IdentityServer4 作为 WSFederation 客户端,带有 .Net Core WSFederation preview2
IdentityServer4 as WSFederation-client with .Net Core WSFederation preview2
我正在尝试将 WSFederation 身份验证提供程序添加到 IdentityServer4。
最近 Microsoft.AspNetCore.Authentication.WsFederation Preview 2 发布了,我可以将其添加到普通的 Asp.NetCore-Application.
但是我很难将它添加到 IdentityServer4 EntityFramework-Quickstart-Example。
这就是我在 Startup 中添加 AuthenticationProvider 的方式。cs/ConfigureServices-method:
services.AddAuthentication()
.AddWsFederation("WsFederation", options =>
{
options.Wtrealm = realm;
options.MetadataAddress = metadata;
})
我在前端获得了 WSFederation 的按钮,我也可以登录。但是在回调之后我得到了这个错误:
InvalidOperationException: sub claim is missing
IdentityServer4.Hosting.IdentityServerAuthenticationService.AssertRequiredClaims(ClaimsPrincipal
principal)
我能理解这是从哪里来的,它是 IdentityServer4 的 IdentityServerAuthenticationService.cs 中的 this line,它需要一个 "sub"-claim - WSFed 没有 return 这样的索赔:
if (principal.FindFirst(JwtClaimTypes.Subject) == null) throw new InvalidOperationException("sub claim is missing");
据我所知,我无法配置此声明,尽管快速启动项目中有一些 tables 似乎可以用于此,尤其是那些 2:
我已经尝试将我想使用的声明而不是主题声明添加到 table,但它似乎没有任何影响,而且我不知道数据库如何映射我在代码中添加的身份提供者。我很乐意提供有关后续步骤的任何提示,或者如果您知道任何示例,那就更好了。
P.S.: 已经有一些关于这个主题的问题,但它们要么是在 WSFederation 的 .Net Core 实现可用之前提出的,要么是参考 WSFederation 服务器的示例,但是不是客户端。
您需要对从 WS-Fed 提供程序返回的声明进行声明转换。通过处理 WS-Fed 处理程序本身的事件 - 或者通过使用快速入门 UI:
中使用的 "ExternalLoginCallback" 模式
感谢@leastprivilege,我实施了以下解决方法来提供子声明:
services.AddAuthentication()
.AddWsFederation("WsFederation", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.Wtrealm = realm;
options.MetadataAddress = metadata;
options.Events.OnTicketReceived += OnTicketReceived;
})
/* some more code inbetween */
/// <summary>
/// Transform the UPN-claim to the sub-claim to be compatible with IdentityServer4
/// </summary>
private async Task OnTicketReceived(TicketReceivedContext ticketReceivedContext)
{
var identity = ticketReceivedContext.Principal.Identities.First();
identity.AddClaim(new Claim("sub", ticketReceivedContext.Principal.FindFirstValue("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")));
}
我正在尝试将 WSFederation 身份验证提供程序添加到 IdentityServer4。 最近 Microsoft.AspNetCore.Authentication.WsFederation Preview 2 发布了,我可以将其添加到普通的 Asp.NetCore-Application.
但是我很难将它添加到 IdentityServer4 EntityFramework-Quickstart-Example。
这就是我在 Startup 中添加 AuthenticationProvider 的方式。cs/ConfigureServices-method:
services.AddAuthentication()
.AddWsFederation("WsFederation", options =>
{
options.Wtrealm = realm;
options.MetadataAddress = metadata;
})
我在前端获得了 WSFederation 的按钮,我也可以登录。但是在回调之后我得到了这个错误:
InvalidOperationException: sub claim is missing IdentityServer4.Hosting.IdentityServerAuthenticationService.AssertRequiredClaims(ClaimsPrincipal principal)
我能理解这是从哪里来的,它是 IdentityServer4 的 IdentityServerAuthenticationService.cs 中的 this line,它需要一个 "sub"-claim - WSFed 没有 return 这样的索赔:
if (principal.FindFirst(JwtClaimTypes.Subject) == null) throw new InvalidOperationException("sub claim is missing");
据我所知,我无法配置此声明,尽管快速启动项目中有一些 tables 似乎可以用于此,尤其是那些 2:
我已经尝试将我想使用的声明而不是主题声明添加到 table,但它似乎没有任何影响,而且我不知道数据库如何映射我在代码中添加的身份提供者。我很乐意提供有关后续步骤的任何提示,或者如果您知道任何示例,那就更好了。
P.S.: 已经有一些关于这个主题的问题,但它们要么是在 WSFederation 的 .Net Core 实现可用之前提出的,要么是参考 WSFederation 服务器的示例,但是不是客户端。
您需要对从 WS-Fed 提供程序返回的声明进行声明转换。通过处理 WS-Fed 处理程序本身的事件 - 或者通过使用快速入门 UI:
中使用的 "ExternalLoginCallback" 模式感谢@leastprivilege,我实施了以下解决方法来提供子声明:
services.AddAuthentication()
.AddWsFederation("WsFederation", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.Wtrealm = realm;
options.MetadataAddress = metadata;
options.Events.OnTicketReceived += OnTicketReceived;
})
/* some more code inbetween */
/// <summary>
/// Transform the UPN-claim to the sub-claim to be compatible with IdentityServer4
/// </summary>
private async Task OnTicketReceived(TicketReceivedContext ticketReceivedContext)
{
var identity = ticketReceivedContext.Principal.Identities.First();
identity.AddClaim(new Claim("sub", ticketReceivedContext.Principal.FindFirstValue("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")));
}