[英]Duende Identity Server : How to return external provider tokens also to the Angular/WPF/MVC client along with Duende tokens
[英]Using Duende Identity Server and RSK SAML Identity Provider Store
我們正在使用 .net 6.0 將我們現有的身份服務器解決方案從 ID4 升級到 Duende 身份服務器
我們還為 Duende 身份服務器使用 RSK 的 SAML 插件。
現在我正在嘗試創建我們自己的 SAML 身份提供程序存儲,而不是提供的 In memory 存儲。
我面臨的問題是 SAML 2p 身份驗證處理程序在調用“HandleChallengeAsync(AuthenticationProperties 屬性)”方法時拋出 null 引用異常。 但它並沒有告訴我 null 參考與什么有關。
在使用 InMemory 實現單步執行代碼時,一切正常。 我附上了創建 SamlDynamicIdentityProvider 以及異常的代碼。
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;
}
任何幫助將不勝感激。
謝謝,高瑟姆
在與 RSK 的支持熱線交談后,我的問題的答案相當簡單。 我不應該在我的 class 中擴展SamlDynamicIdentityProvider
,而只是實現IIdentityProviderStore
。
Class 定義現在是 - public class SamlIdPStore: IIdentityProviderStore
一切正常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.