hi
Add MyAbpValidatePostLogoutRedirectUriParameter and MyAbpValidateClientPostLogoutRedirectUri to support the wildcard domain.
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<OpenIddictServerBuilder>(builder =>
{
builder.RemoveEventHandler(AbpValidatePostLogoutRedirectUriParameter.Descriptor);
builder.AddEventHandler(MyAbpValidatePostLogoutRedirectUriParameter.Descriptor);
builder.RemoveEventHandler(AbpValidateClientPostLogoutRedirectUri.Descriptor);
builder.AddEventHandler(MyAbpValidateClientPostLogoutRedirectUri.Descriptor);
});
PreConfigure<AbpOpenIddictWildcardDomainOptions>(options =>
{
options.EnableWildcardDomainSupport = true;
options.WildcardDomainsFormat.Add("http://127.0.0.1:{0}");
});
}
using Microsoft.Extensions.Options;
using OpenIddict.Abstractions;
using OpenIddict.Server;
using Volo.Abp;
using Volo.Abp.Http;
using Volo.Abp.OpenIddict.WildcardDomains;
using Volo.Abp.Text.Formatting;
namespace OpenIddict.Demo.Server;
public class MyAbpValidatePostLogoutRedirectUriParameter : AbpOpenIddictWildcardDomainBase<MyAbpValidatePostLogoutRedirectUriParameter, OpenIddictServerHandlers.Session.ValidatePostLogoutRedirectUriParameter, OpenIddictServerEvents.ValidateEndSessionRequestContext>
{
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<OpenIddictServerEvents.ValidateEndSessionRequestContext>()
.UseSingletonHandler<MyAbpValidatePostLogoutRedirectUriParameter>()
.SetOrder(int.MinValue + 100_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
public MyAbpValidatePostLogoutRedirectUriParameter(IOptions<AbpOpenIddictWildcardDomainOptions> wildcardDomainsOptions)
: base(wildcardDomainsOptions, new OpenIddictServerHandlers.Session.ValidatePostLogoutRedirectUriParameter())
{
}
public override async ValueTask HandleAsync(OpenIddictServerEvents.ValidateEndSessionRequestContext context)
{
Check.NotNull(context, nameof(context));
if (string.IsNullOrEmpty(context.PostLogoutRedirectUri) || await CheckWildcardDomainAsync(context.PostLogoutRedirectUri))
{
return;
}
await OriginalHandler.HandleAsync(context);
}
protected override Task<bool> CheckWildcardDomainAsync(string url)
{
if (WildcardDomainOptions.WildcardDomainsFormat.IsNullOrEmpty())
{
Logger.LogDebug("No wildcard domain format configured.");
return Task.FromResult(false);
}
Logger.LogDebug("Checking wildcard domain for url: {url}", url);
foreach (var domain in WildcardDomainOptions.WildcardDomainsFormat.Select(domainFormat => domainFormat.Replace("{0}", "*")))
{
Logger.LogDebug("Checking wildcard domain format: {domain}", domain);
if (UrlHelpers.IsSubdomainOf(url, domain))
{
Logger.LogDebug("The url: {url} is a wildcard domain of: {domain}", url, domain);
return Task.FromResult(true);
}
}
foreach (var domain in WildcardDomainOptions.WildcardDomainsFormat)
{
Logger.LogDebug("Checking wildcard domain format: {domainFormat}", domain);
var extractResult = FormattedStringValueExtracter.Extract(url, domain, ignoreCase: true);
if (extractResult.IsMatch)
{
Logger.LogDebug("Wildcard domain found for url: {url}", url);
return Task.FromResult(true);
}
}
Logger.LogDebug("No wildcard domain found for url: {url}", url);
return Task.FromResult(false);
}
}
public class MyAbpValidateClientPostLogoutRedirectUri : AbpOpenIddictWildcardDomainBase<MyAbpValidateClientPostLogoutRedirectUri, OpenIddictServerHandlers.Session.ValidateClientPostLogoutRedirectUri, OpenIddictServerEvents.ValidateEndSessionRequestContext>
{
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<OpenIddictServerEvents.ValidateEndSessionRequestContext>()
.AddFilter<OpenIddictServerHandlerFilters.RequireDegradedModeDisabled>()
.AddFilter<OpenIddictServerHandlerFilters.RequirePostLogoutRedirectUriParameter>()
.UseScopedHandler<MyAbpValidateClientPostLogoutRedirectUri>()
.SetOrder(OpenIddictServerHandlers.Session.ValidatePostLogoutRedirectUriParameter.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
public MyAbpValidateClientPostLogoutRedirectUri(
IOptions<AbpOpenIddictWildcardDomainOptions> wildcardDomainsOptions,
IOpenIddictApplicationManager applicationManager)
: base(wildcardDomainsOptions, new OpenIddictServerHandlers.Session.ValidateClientPostLogoutRedirectUri(applicationManager))
{
OriginalHandler = new OpenIddictServerHandlers.Session.ValidateClientPostLogoutRedirectUri(applicationManager);
}
public override async ValueTask HandleAsync(OpenIddictServerEvents.ValidateEndSessionRequestContext context)
{
Check.NotNull(context, nameof(context));
Check.NotNullOrEmpty(context.PostLogoutRedirectUri, nameof(context.PostLogoutRedirectUri));
if (await CheckWildcardDomainAsync(context.PostLogoutRedirectUri))
{
return;
}
await OriginalHandler.HandleAsync(context);
}
protected override Task<bool> CheckWildcardDomainAsync(string url)
{
if (WildcardDomainOptions.WildcardDomainsFormat.IsNullOrEmpty())
{
Logger.LogDebug("No wildcard domain format configured.");
return Task.FromResult(false);
}
Logger.LogDebug("Checking wildcard domain for url: {url}", url);
foreach (var domain in WildcardDomainOptions.WildcardDomainsFormat.Select(domainFormat => domainFormat.Replace("{0}", "*")))
{
Logger.LogDebug("Checking wildcard domain format: {domain}", domain);
if (UrlHelpers.IsSubdomainOf(url, domain))
{
Logger.LogDebug("The url: {url} is a wildcard domain of: {domain}", url, domain);
return Task.FromResult(true);
}
}
foreach (var domain in WildcardDomainOptions.WildcardDomainsFormat)
{
Logger.LogDebug("Checking wildcard domain format: {domainFormat}", domain);
var extractResult = FormattedStringValueExtracter.Extract(url, domain, ignoreCase: true);
if (extractResult.IsMatch)
{
Logger.LogDebug("Wildcard domain found for url: {url}", url);
return Task.FromResult(true);
}
}
Logger.LogDebug("No wildcard domain found for url: {url}", url);
return Task.FromResult(false);
}
}
hi
Could you share a demo project that reproduces the problem?
liming.ma@volosoft.com Thanks
hi
You can remove all settings of Abp.Account.ExternalProviders,Then add them in your setting page again.
After that, everything will work.
Because the template project is no problem.
Thanks.
hi Can you try with a new database or clear the setting from database.
If still not working can share your test project?
liming.ma@volosoft.com
Thanks.
Ok
Unlocked. Please share the problem details. Thanks
Hi
You can inject AbpApplicationManager to update application/client entity.
https://abp.io/docs/latest/modules/openiddict#database-providers
hi
Add BankIdOpenIddictServerHandler to your AuthServer project
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<OpenIddictServerBuilder>(builder =>
{
builder.AddEventHandler(BankIdOpenIddictServerHandler.Descriptor);
});
}
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using OpenIddict.Abstractions;
using OpenIddict.Server;
namespace BankIdDemo;
public class BankIdOpenIddictServerHandler : IOpenIddictServerHandler<OpenIddictServerEvents.ProcessSignInContext>
{
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<OpenIddictServerEvents.ProcessSignInContext>()
.UseSingletonHandler<BankIdOpenIddictServerHandler>()
.SetOrder(100_000)
.SetType(OpenIddictServerHandlerType.Custom)
.Build();
public async ValueTask HandleAsync(OpenIddictServerEvents.ProcessSignInContext context)
{
if (context is { EndpointType: OpenIddictServerEndpointType.Authorization, AuthorizationCodePrincipal: not null})
{
var httpContext = context.Transaction.GetHttpRequest()?.HttpContext;
if (httpContext == null)
{
return;
}
var identity = await httpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme);
if (identity?.Principal == null)
{
return;
}
var nationalidentitynumber =identity?.Principal?.FindFirst("nationalidentitynumber")?.Value;
if (!nationalidentitynumber.IsNullOrWhiteSpace())
{
context.AuthorizationCodePrincipal?.AddClaim("nationalidentitynumber", nationalidentitynumber);
}
return;
}
if (context is { EndpointType: OpenIddictServerEndpointType.Token, AccessTokenPrincipal: not null})
{
var nationalidentitynumber = context.AccessTokenPrincipal?.FindFirst("nationalidentitynumber")?.Value;
if (!nationalidentitynumber.IsNullOrWhiteSpace())
{
context.AccessTokenPrincipal?.AddClaim("nationalidentitynumber", nationalidentitynumber);
}
}
}
}
Great 👍
hi
Add the code below to fix the ReturnUrl issue. I will fix it in the next version
Thanks
Configure<AbpAccountOptions>(options =>
{
options.GetTenantDomain = (httpContext, tenantInfo) =>
{
var returnUrl = "";
if (httpContext.Request.HasFormContentType)
{
var form = httpContext.Request.Form;
if (form.ContainsKey("ReturnUrl"))
{
returnUrl = form["ReturnUrl"];
}
}
return Task.FromResult(httpContext.Request.Scheme + "://" + httpContext.Request.Host + httpContext.Request.PathBase + returnUrl);
};
});