Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AbpStrictRedirectUriValidator to compatible with tenant name in domain. #7783

Merged
merged 3 commits into from
Feb 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
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)
{
services.Replace(ServiceDescriptor.Transient<IRedirectUriValidator, AbpStrictRedirectUriValidator>());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using IdentityServer4.Models;
using IdentityServer4.Validation;
using Microsoft.Extensions.Options;
using Volo.Abp.Text.Formatting;

namespace Volo.Abp.IdentityServer
{
public class AbpStrictRedirectUriValidator : StrictRedirectUriValidator
{
public override async Task<bool> IsRedirectUriValidAsync(string requestedUri, Client client)
{
var isAllowed = await base.IsRedirectUriValidAsync(requestedUri, client);
return isAllowed || await IsRedirectUriValidWithDomainFormatsAsync(client.RedirectUris, requestedUri);
}

public override async Task<bool> IsPostLogoutRedirectUriValidAsync(string requestedUri, Client client)
{
var isAllowed = await base.IsPostLogoutRedirectUriValidAsync(requestedUri, client);
return isAllowed || await IsRedirectUriValidWithDomainFormatsAsync(client.PostLogoutRedirectUris, requestedUri);
}

protected virtual Task<bool> IsRedirectUriValidWithDomainFormatsAsync(IEnumerable<string> uris, string requestedUri)
{
if (uris == null)
{
return Task.FromResult(false);
}

foreach (var url in uris)
{
var extractResult = FormattedStringValueExtracter.Extract(requestedUri, url, ignoreCase: true);
if (extractResult.IsMatch)
{
return Task.FromResult(true);
}
}

return Task.FromResult(false);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using IdentityServer4.Models;
using IdentityServer4.Validation;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Xunit;

namespace Volo.Abp.IdentityServer
{
public class AbpStrictRedirectUriValidator_Tests : AbpIdentityServerTestBase
{
private readonly IRedirectUriValidator _abpStrictRedirectUriValidator;

private readonly Client _testClient = new Client
{
RedirectUris = new List<string>
{
"https://{0}.api.abp.io:8080/signin-oidc",
"http://{0}.ng.abp.io/index.html"
},
PostLogoutRedirectUris = new List<string>
{
"https://{0}.api.abp.io:8080/signin-oidc",
"http://{0}.ng.abp.io/index.html"
}
};

public AbpStrictRedirectUriValidator_Tests()
{
_abpStrictRedirectUriValidator = GetRequiredService<IRedirectUriValidator>();
}

protected override void AfterAddApplication(IServiceCollection services)
{
services.AddAbpStrictRedirectUriValidator();
}

[Fact]
public void Should_Register_AbpStrictRedirectUriValidator()
{
_abpStrictRedirectUriValidator.GetType().ShouldBe(typeof(AbpStrictRedirectUriValidator));
}

[Fact]
public async Task IsRedirectUriValidAsync()
{
(await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("https://t1.api.abp.io:8080/signin-oidc", _testClient)).ShouldBeTrue();
(await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("http://t2.ng.abp.io/index.html", _testClient)).ShouldBeTrue();

(await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("https://api.abp:8080/", _testClient)).ShouldBeFalse();
(await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("http://ng.abp.io", _testClient)).ShouldBeFalse();
(await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("https://api.t1.abp:8080/", _testClient)).ShouldBeFalse();
(await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("http://ng.t1.abp.io", _testClient)).ShouldBeFalse();
}

[Fact]
public async Task IsPostLogoutRedirectUriValidAsync()
{
(await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("https://t1.api.abp.io:8080/signin-oidc", _testClient)).ShouldBeTrue();
(await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("http://t2.ng.abp.io/index.html", _testClient)).ShouldBeTrue();

(await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("https://api.abp:8080/", _testClient)).ShouldBeFalse();
(await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("http://ng.abp.io", _testClient)).ShouldBeFalse();
(await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("https://api.t1.abp:8080/", _testClient)).ShouldBeFalse();
(await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("http://ng.t1.abp.io", _testClient)).ShouldBeFalse();
}
}
}