Skip to content

Commit

Permalink
Merge pull request #20628 from abpframework/UriHelpers
Browse files Browse the repository at this point in the history
Support wildcard domain in `AppUrlProvider `.
  • Loading branch information
EngincanV authored Aug 27, 2024
2 parents 64788f4 + 52c9554 commit 3f020e8
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 4 deletions.
28 changes: 28 additions & 0 deletions framework/src/Volo.Abp.Core/Volo/Abp/Http/UrlHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;

namespace Volo.Abp.Http;

public static class UrlHelpers
{
private const string WildcardSubdomain = "*.";

public static bool IsSubdomainOf(string subdomain, string domain)
{
if (Uri.TryCreate(subdomain, UriKind.Absolute, out var subdomainUri) &&
Uri.TryCreate(domain.Replace(WildcardSubdomain, string.Empty), UriKind.Absolute, out var domainUri))
{
return domainUri == subdomainUri || IsSubdomainOf(subdomainUri, domainUri);
}

return false;
}

public static bool IsSubdomainOf(Uri subdomain, Uri domain)
{
return subdomain.IsAbsoluteUri
&& domain.IsAbsoluteUri
&& subdomain.Scheme == domain.Scheme
&& subdomain.Port == domain.Port
&& subdomain.Host.EndsWith($".{domain.Host}", StringComparison.Ordinal);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http;
using Volo.Abp.MultiTenancy;

namespace Volo.Abp.UI.Navigation.Urls;
Expand Down Expand Up @@ -43,7 +44,8 @@ public virtual async Task<bool> IsRedirectAllowedUrlAsync(string url)
{
redirectAllowedUrls.Add((await NormalizeUrlAsync(redirectAllowedUrl))!);
}
var allow = redirectAllowedUrls.Any(x => url.StartsWith(x, StringComparison.CurrentCultureIgnoreCase));
var allow = redirectAllowedUrls.Any(x => url.StartsWith(x, StringComparison.CurrentCultureIgnoreCase) ||
UrlHelpers.IsSubdomainOf(url, x));
if (!allow)
{
Logger.LogError($"Invalid RedirectUrl: {url}, Use {nameof(AppUrlProvider)} to configure it!");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Shouldly;
using Xunit;

namespace Volo.Abp.Http;

public class UrlHelpers_Tests
{
[Theory]
[InlineData(null)]
[InlineData("null")]
[InlineData("http://")]
[InlineData("http://*")]
[InlineData("http://.domain")]
[InlineData("http://.domain/hello")]
public void IsSubdomainOf_ReturnsFalseIfDomainIsMalformedUri(string domain)
{
var actual = UrlHelpers.IsSubdomainOf("http://*.domain", domain);
actual.ShouldBeFalse();
}

[Theory]
[InlineData("http://sub.domain", "http://domain")]
[InlineData("http://sub.domain", "http://*.domain")]
[InlineData("http://sub.sub.domain", "http://*.domain")]
[InlineData("http://sub.sub.domain", "http://*.sub.domain")]
[InlineData("http://sub.domain:4567", "http://*.domain:4567")]
public void IsSubdomainOf_ReturnsTrue_WhenASubdomain(string subdomain, string domain)
{
var actual = UrlHelpers.IsSubdomainOf(subdomain, domain);
actual.ShouldBeTrue();
}

[Theory]
[InlineData("http://sub.domain:1234", "http://*.domain:5678")]
[InlineData("http://sub.domain", "http://domain.*")]
[InlineData("http://sub.domain.hacker", "http://*.domain")]
[InlineData("https://sub.domain", "http://*.domain")]
public void IsSubdomainOf_ReturnsFalse_WhenNotASubdomain(string subdomain, string domain)
{
var actual = UrlHelpers.IsSubdomainOf(subdomain, domain);
actual.ShouldBeFalse();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ protected override void AfterAddApplication(IServiceCollection services)
"https://wwww.volosoft.com",
"https://wwww.aspnetzero.com",
"https://{{tenantName}}.abp.io",
"https://{{tenantId}}.abp.io"
"https://{{tenantId}}.abp.io",
"https://*.demo.myabp.io"
});

options.Applications["BLAZOR"].RootUrl = "https://{{tenantId}}.abp.io";
Expand Down Expand Up @@ -101,12 +102,16 @@ public async Task GetUrlOrNullAsync()
[Fact]
public async Task IsRedirectAllowedUrlAsync()
{
(await _appUrlProvider.IsRedirectAllowedUrlAsync("https://community.abp.io")).ShouldBeFalse();
(await _appUrlProvider.IsRedirectAllowedUrlAsync("https://wwww.volosoft.com")).ShouldBeTrue();
(await _appUrlProvider.IsRedirectAllowedUrlAsync("https://wwww.demo.myabp.io")).ShouldBeTrue();
(await _appUrlProvider.IsRedirectAllowedUrlAsync("https://demo.myabp.io")).ShouldBeTrue();
(await _appUrlProvider.IsRedirectAllowedUrlAsync("https://api.demo.myabp.io")).ShouldBeTrue();
(await _appUrlProvider.IsRedirectAllowedUrlAsync("https://test.api.demo.myabp.io")).ShouldBeTrue();
(await _appUrlProvider.IsRedirectAllowedUrlAsync("https://volosoft.com/demo.myabp.io")).ShouldBeFalse();
(await _appUrlProvider.IsRedirectAllowedUrlAsync("https://wwww.myabp.io")).ShouldBeFalse();

using (_currentTenant.Change(null))
{
(await _appUrlProvider.IsRedirectAllowedUrlAsync("https://www.abp.io")).ShouldBeFalse();
(await _appUrlProvider.IsRedirectAllowedUrlAsync("https://abp.io")).ShouldBeTrue();
}

Expand Down

0 comments on commit 3f020e8

Please sign in to comment.