From c20a5b370e7f3d9d944c768d91b908f43ff755db Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 19 Feb 2021 19:18:19 +0800 Subject: [PATCH] Add AbpStrictRedirectUriValidator to compatible with tenant name in domain. --- ...entityServerServiceCollectionExtensions.cs | 19 +++++ .../AbpRedirectUriValidatorOptions.cs | 7 ++ .../AbpStrictRedirectUriValidator.cs | 83 +++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerServiceCollectionExtensions.cs create mode 100644 modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpRedirectUriValidatorOptions.cs create mode 100644 modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpStrictRedirectUriValidator.cs diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerServiceCollectionExtensions.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerServiceCollectionExtensions.cs new file mode 100644 index 0000000000..633719ae9b --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerServiceCollectionExtensions.cs @@ -0,0 +1,19 @@ +using IdentityServer4.Validation; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Volo.Abp.IdentityServer +{ + public static class AbpIdentityServerServiceCollectionExtensions + { + public static void AddAbpStrictRedirectUriValidator(this IServiceCollection services, string domainFormat) + { + services.Configure(options => + { + options.DomainFormat = domainFormat; + }); + + services.Replace(ServiceDescriptor.Transient()); + } + } +} diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpRedirectUriValidatorOptions.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpRedirectUriValidatorOptions.cs new file mode 100644 index 0000000000..082aeb4523 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpRedirectUriValidatorOptions.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.IdentityServer +{ + public class AbpRedirectUriValidatorOptions + { + public string DomainFormat { get; set; } + } +} diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpStrictRedirectUriValidator.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpStrictRedirectUriValidator.cs new file mode 100644 index 0000000000..50baadaf2b --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpStrictRedirectUriValidator.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using IdentityServer4.Models; +using IdentityServer4.Validation; +using Microsoft.Extensions.Options; +using Volo.Abp.Text.Formatting; + +namespace Volo.Abp.IdentityServer +{ + /// + /// Default implementation of redirect URI validator. Validates the URIs against + /// the client's configured URIs. + /// + public class AbpStrictRedirectUriValidator : IRedirectUriValidator + { + protected AbpRedirectUriValidatorOptions Options { get; } + + public AbpStrictRedirectUriValidator(IOptions options) + { + Options = options.Value; + } + + /// + /// Checks if a given URI string is in a collection of strings (using ordinal ignore case comparison) + /// + /// The uris. + /// The requested URI. + /// + protected virtual bool StringCollectionContainsString(IEnumerable uris, string requestedUri) + { + if (uris == null) + { + return false; + } + + foreach (var url in uris) + { + if (url.Contains(requestedUri, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + if (url.Contains(Options.DomainFormat)) + { + var extractResult = FormattedStringValueExtracter.Extract(requestedUri, url, ignoreCase: true); + if (extractResult.IsMatch) + { + return true; + } + } + } + + return false; + } + + /// + /// Determines whether a redirect URI is valid for a client. + /// + /// The requested URI. + /// The client. + /// + /// true is the URI is valid; false otherwise. + /// + public virtual Task IsRedirectUriValidAsync(string requestedUri, Client client) + { + return Task.FromResult(StringCollectionContainsString(client.RedirectUris, requestedUri)); + } + + /// + /// Determines whether a post logout URI is valid for a client. + /// + /// The requested URI. + /// The client. + /// + /// true is the URI is valid; false otherwise. + /// + public virtual Task IsPostLogoutRedirectUriValidAsync(string requestedUri, Client client) + { + return Task.FromResult(StringCollectionContainsString(client.PostLogoutRedirectUris, requestedUri)); + } + } +}