BEST
DEALS
OF THE
YEAR!
SAVE UP TO $3,000
24 NOV
1 DEC
00 Days
00 Hrs
00 Min
00 Sec

Activities of "rogercprops"

We're considering deploying our microservices solution to Azure Container Apps vs Kubernetes. Has anyone done this before and if so, are there documents / templates to follow?

Hi,

In the Identity service OpenIddictDataSeeder on this block of code:

if (!Uri.TryCreate(redirectUri, UriKind.Absolute, out var uri) || !uri.IsWellFormedOriginalString())
                {
                    throw new ApplicationException("Invalid redirect URI: " + redirectUri);
                }

We get:

Exception has occurred: CLR/System.ApplicationException
An exception of type 'System.ApplicationException' occurred in System.Private.CoreLib.dll but was not handled in user code: 'Invalid redirect URI: https://{0}.mydomain.dev/signin-oidc'
   at CloverleafCMS.IdentityService.Data.OpenIddictDataSeeder.<CreateOrUpdateApplicationAsync>d__15.MoveNext() in /Users/rogerhopkins/App_Development/CodeRepositories/CloverleafCMS-Microservices/services/identity/CloverleafCMS.IdentityService/Data/OpenIddictDataSeeder.cs:line 627
   at CloverleafCMS.IdentityService.Data.OpenIddictDataSeeder.<CreateClientsAsync>d__14.MoveNext() in /Users/rogerhopkins/App_Development/CodeRepositories/CloverleafCMS-Microservices/services/identity/CloverleafCMS.IdentityService/Data/OpenIddictDataSeeder.cs:line 354
   at CloverleafCMS.IdentityService.Data.OpenIddictDataSeeder.<SeedAsync>d__9.MoveNext() in /Users/rogerhopkins/App_Development/CodeRepositories/CloverleafCMS-Microservices/services/identity/CloverleafCMS.IdentityService/Data/OpenIddictDataSeeder.cs:line 57
   at Castle.DynamicProxy.AsyncInterceptorBase.<ProceedAsynchronous>d__13.MoveNext()
   at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapter.<ProceedAsync>d__7.MoveNext()
   at Volo.Abp.Uow.UnitOfWorkInterceptor.<InterceptAsync>d__2.MoveNext()
   at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.&lt;InterceptAsync&gt;d__2.MoveNext()
   at CloverleafCMS.IdentityService.Data.IdentityServiceDataSeeder.&lt;SeedOpenIddictAsync&gt;d__12.MoveNext() in /Users/rogerhopkins/App_Development/CodeRepositories/CloverleafCMS-Microservices/services/identity/CloverleafCMS.IdentityService/Data/IdentityServiceDataSeeder.cs:line 105
   at CloverleafCMS.IdentityService.Data.IdentityServiceDataSeeder.&lt;SeedAsync&gt;d__9.MoveNext() in /Users/rogerhopkins/App_Development/CodeRepositories/CloverleafCMS-Microservices/services/identity/CloverleafCMS.IdentityService/Data/IdentityServiceDataSeeder.cs:line 52
   at CloverleafCMS.IdentityService.Data.IdentityServiceRuntimeDatabaseMigrator.&lt;SeedAsync&gt;d__2.MoveNext() in /Users/rogerhopkins/App_Development/CodeRepositories/CloverleafCMS-Microservices/services/identity/CloverleafCMS.IdentityService/Data/IdentityServiceRuntimeDatabaseMigrator.cs:line 35
   at Volo.Abp.EntityFrameworkCore.Migrations.EfCoreRuntimeDatabaseMigratorBase`1.<LockAndApplyDatabaseMigrationsAsync>d__35.MoveNext()

We've already done the above. We added "https://{0}.mydomain.dev/" to the appsettings in the Identity service and it threw an error that it's a malformed url in the CreateOrUpdateApplicationAsync of OpenIddictDataSeeder.cs.

We have a Saas web application written in Vue JS that uses our Abp Microservice solution for the backend. Each tenant will have their own domain like https://client1.mydomain, https://client2.mydomain.dev, etc.

We added this to the auth server module PreconfigureServices PreConfigure(options => { options.EnableWildcardDomainSupport = true; // Development environment domains options.WildcardDomainsFormat.Add("https://{0}.mydomain.dev/signin-oidc"); options.WildcardDomainsFormat.Add("https://{0}.mydomain.dev/silent-refresh"); options.WildcardDomainsFormat.Add("https://{0}.mydomain.dev/auth/login"); options.WildcardDomainsFormat.Add("https://{0}.mydomain.dev/auth/signout-callback-oidc"); });

In the Identity database OpenIddictApplications table we manually updated the RedirectUris and PostLogoutRedirectUris with the wildcard character '*'

[
{
"id": "9335f213-8a0d-7ce3-f069-3a1b786183db",
"ClientId": "CloverleafCMS",
"RedirectUris": "["https://*.mydomain.dev/signin-oidc","https://*.mydomain.dev/auth/silent-refresh"]",
"PostLogoutRedirectUris": "["https://.cloverleafcms.us/auth/login"]"

}

]

The issue is that the OpenIddictApplications table is reseeded every time the Identity service is restarted. So we have to manually update the redirect Uris with the wildcard manually

I tried adding the wildcard in the Identity data seeder but it through a malformed url error.

I read this article https://abp.io/docs/latest/guides/ms-multi-tenant-domain-resolving but not sure that will fix our problem since our client application is written in Vue.

How do we get around this? <br>

I think this fixed it.

Thank you.

I just granted you access to the Token service and auth-server GitHub repositories

I made the change to the token service passing var policy = new DiscoveryPolicy

{
    RequireHttps = false
};

and am now getting this error

{
    "error": {
        "code": null,
        "message": "Error retrieving discovery document: Invalid base address for endpoint http://authserver.mydomain.dev/connect/authorize. Valid base addresses: https://authserver.mydomain.dev.",
        "details": null,
        "data": {},
        "validationErrors": null
    }
}

This answer still doesn't make sense. We have not touched the Token service since 8/27. But I just made a change to the authserver and redeployed. It's now working again (not throwing a http error and successfully returning a token).

So something else must be happening.

Set it where?

DiscoveryCache is from the Duende.IdentityModel package

// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using Duende.IdentityModel.Internal;

namespace Duende.IdentityModel.Client;

/// <summary>
/// Helper for caching discovery documents.
/// </summary>
public class DiscoveryCache : IDiscoveryCache
{
    private DateTime _nextReload = DateTime.MinValue;
    private AsyncLazy<DiscoveryDocumentResponse>? _lazyResponse;

    private readonly DiscoveryPolicy _policy;
    private readonly Func<HttpMessageInvoker> _getHttpClient;
    private readonly string _authority;

    /// <summary>
    /// Initialize instance of DiscoveryCache with passed authority.
    /// </summary>
    /// <param name="authority">Base address or discovery document endpoint.</param>
    /// <param name="policy">The policy.</param>
    public DiscoveryCache(string authority, DiscoveryPolicy? policy = null)
    {
        _authority = authority;
        _policy = policy ?? new DiscoveryPolicy();
        _getHttpClient = () => new HttpClient();
    }

    /// <summary>
    /// Initialize instance of DiscoveryCache with passed authority.
    /// </summary>
    /// <param name="authority">Base address or discovery document endpoint.</param>
    /// <param name="httpClientFunc">The HTTP client function.</param>
    /// <param name="policy">The policy.</param>
    public DiscoveryCache(string authority, Func<HttpMessageInvoker> httpClientFunc, DiscoveryPolicy? policy = null)
    {
        _authority = authority;
        _policy = policy ?? new DiscoveryPolicy();
        _getHttpClient = httpClientFunc ?? throw new ArgumentNullException(nameof(httpClientFunc));
    }

    /// <summary>
    /// Frequency to refresh discovery document. Defaults to 24 hours.
    /// </summary>
    public TimeSpan CacheDuration { get; set; } = TimeSpan.FromHours(24);

    /// <summary>
    /// Get the DiscoveryResponse either from cache or from discovery endpoint.
    /// </summary>
    /// <returns></returns>
    public Task<DiscoveryDocumentResponse> GetAsync()
    {
        if (_nextReload <= DateTime.UtcNow)
        {
            Refresh();
        }

        return _lazyResponse!.Value;
    }

    /// <summary>
    /// Marks the discovery document as stale and will trigger a request to the discovery endpoint on the next request to get the DiscoveryResponse.
    /// </summary>
    public void Refresh()
    {
        _lazyResponse = new AsyncLazy<DiscoveryDocumentResponse>(GetResponseAsync);
    }

    private async Task<DiscoveryDocumentResponse> GetResponseAsync()
    {
        var result = await _getHttpClient().GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
        {
            Address = _authority,
            Policy = _policy
        }).ConfigureAwait();

        if (result.IsError)
        {
            Refresh();
            _nextReload = DateTime.MinValue;
        }
        else
        {
            _nextReload = DateTime.UtcNow.Add(CacheDuration);
        }

        return result;
    }
}
Showing 1 to 10 of 101 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.1.0-preview. Updated on November 20, 2025, 09:12
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.