Using Duende Identity Server and RSK SAML Identity Provider



我们正在使用.net 6.0 将现有的Identity Server解决方案从ID4升级为Duende Identity Server

我们还将RSK的SAML插件用于Duende Identity Server。

现在,我正在尝试创建我们自己的SAML Identity Provider存储,而不是提供的内存存储。

我面临的问题是SAML2p身份验证处理程序在调用";HandleChallengeSync(AuthenticationProperties属性(";方法但它并没有告诉我空引用与什么有关。

当使用InMemory实现逐步执行代码时,一切都正常。我附加了创建SamlDynamicIdentityProvider的代码以及异常。

Saml IdP存储

public class SamlIdPStore : SamlDynamicIdentityProvider, IIdentityProviderStore
{
private readonly ILogger _logger;
private readonly IEnumerable<IdentityProvider> _providers;
/*
public SamlIdPStore(ILogger logger)
{
_logger = logger;
}
*/

public SamlIdPStore(IEnumerable<IdentityProvider> providers, ILogger logger)
{
_logger = logger;
_providers = providers;
}

public async Task<IEnumerable<IdentityProviderName>> GetAllSchemeNamesAsync()
{
var samlIdPConfigs = await SamlIdPConfigurationManagerFactory.GetAllSamlIdPConfigs();
var identityProviderNames = new List<IdentityProviderName>();
foreach (var samlIdPConfig in samlIdPConfigs)
{
var identityProviderName = new IdentityProviderName()
{
DisplayName = samlIdPConfig.DisplayName,
Enabled = true,
Scheme = samlIdPConfig.AuthenticationScheme
};
identityProviderNames.Add(identityProviderName);
}
return identityProviderNames;
}
public async Task<IdentityProvider> GetBySchemeAsync(string scheme)
{
var samlIdentityProvider = await SamlIdPConfigurationManagerFactory.GetSamlIdPConfig(scheme);
var identityProvider = new IdentityProvider("saml2p")
{
Scheme = scheme,
DisplayName = samlIdentityProvider.DisplayName,
Enabled = true

};

var samlDynamicProvider = Saml2p.CreateDynamicProviderFromConfig(samlIdentityProvider, _logger);
identityProvider.Properties = samlDynamicProvider.Properties;
return identityProvider;
}
}

我们得到的例外是-

System.NullReferenceException: Object reference not set to an instance of an object.
at Rsk.AspNetCore.Authentication.Saml2p.Saml2pAuthenticationHandler.HandleChallengeAsync(AuthenticationProperties properties)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.ChallengeAsync(AuthenticationProperties properties)
at Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, String scheme, AuthenticationProperties properties)
at Microsoft.AspNetCore.Mvc.ChallengeResult.ExecuteResultAsync(ActionContext context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultAsync>g__Logged|22_0(ResourceInvoker invoker, IActionResult result)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Rsk.Saml.Hosting.IdentityServerSamlMiddleware.Invoke(HttpContext context, ISamlEndpointRouter router, ISamlEventService eventService, SamlIdpOptions options)
at Duende.IdentityServer.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events, IIssuerNameService issuerNameService, IBackChannelLogoutService backChannelLogoutService) in /_/src/IdentityServer/Hosting/IdentityServerMiddleware.cs:line 102
at Duende.IdentityServer.Hosting.MutualTlsEndpointMiddleware.Invoke(HttpContext context, IAuthenticationSchemeProvider schemes) in /_/src/IdentityServer/Hosting/MutualTlsEndpointMiddleware.cs:line 94
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Duende.IdentityServer.Hosting.DynamicProviders.DynamicSchemeAuthenticationMiddleware.Invoke(HttpContext context) in /_/src/IdentityServer/Hosting/DynamicProviders/DynamicSchemes/DynamicSchemeAuthenticationMiddleware.cs:line 47
at Duende.IdentityServer.Hosting.BaseUrlMiddleware.Invoke(HttpContext context) in /_/src/IdentityServer/Hosting/BaseUrlMiddleware.cs:line 27
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

内存中实现

public static IIdentityServerBuilder AddSaml2pIdPFromConfiguration(this IIdentityServerBuilder builder,
 ISamlIdpConfigurationManager idpConfigManager,
 ILogger logger)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
//only create the SAML IDP if we have a valid key in the config file
if (string.IsNullOrWhiteSpace(ConfigSettings.SamlLicenseKey))
{
return builder;
}
try
{
builder.AddSamlDynamicProvider(options =>
{
options.Licensee = ConfigSettings.SamlLicensee;
options.LicenseKey = ConfigSettings.SamlLicenseKey;
});
// add saml2p as defined by each configuration in the saml configuation file
var samlDynamicIdentityProviders = new List<SamlDynamicIdentityProvider>();
foreach (var samlIdpConfig in idpConfigManager.GetIdpConfigurations())
{
var samlDynamicIdentityProvider = CreateDynamicProviderFromConfig(samlIdpConfig,logger);
samlDynamicIdentityProviders.Add(samlDynamicIdentityProvider);
}
builder.AddInMemoryIdentityProviders(samlDynamicIdentityProviders);
//builder.AddIdentityProviderStore<SamlIdPStore>();
}
catch (Exception ex)
{
logger?.LogError(ex, $"Error adding SAML2P idp configuration");
}

return builder;
}

如有任何帮助,我们将不胜感激。

谢谢,Gautham

在与RSK的支持热线交谈后,我的问题的答案相当简单。我不应该在类中扩展SamlDynamicIdentityProvider,而只是实现IIdentityProviderStore

类定义现在-public class SamlIdPStore : IIdentityProviderStore

一切正常。

最新更新