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

The remote certificate is invalid according to the validation procedure: RemoteCertificateNameMismatch #22046

Open
caiocollete opened this issue Jan 29, 2025 · 10 comments

Comments

@caiocollete
Copy link

I'm developing a project using a Domain Tenant Resolver, I can do login in default tenant with admin master, but when I try to log in with the tenant, I receive an error message:

AuthenticationException: The remote certificate is invalid according to the validation procedure: RemoteCertificateNameMismatch
System.Net.Security.SslStream.CompleteHandshake(SslAuthenticationOptions sslAuthenticationOptions)

HttpRequestException: The SSL connection could not be established, see inner exception.
System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, bool async, Stream stream, CancellationToken cancellationToken)

AuthServer/appsetings.json:

  "App": {
    "SelfUrl": "https://localhost:44355",
    "CorsOrigins": "https://*.Beta01.com,http://localhost:4200,https://localhost:44359,https://localhost:44389,https://localhost:44325",
    "RedirectAllowedUrls": "http://localhost:4200,https://localhost:44363,https://localhost:44359,https://localhost:44360,https://localhost:44389",
    "DisablePII": false
  },
  "ConnectionStrings": {
    "Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=Beta01-Personal;Trusted_Connection=True;TrustServerCertificate=true"
  },
  "AuthServer": {
    "Authority": "https://localhost:44355",
    "RequireHttpsMetadata": true,
    "CertificatePassPhrase": "6132db5f-9ddf-42b3-965d-b4d189f754dc"
  },
  "StringEncryption": {
    "DefaultPassPhrase": "mhvLo8IhGumjXM6Z"
  },
  "Redis": {
    "Configuration": "127.0.0.1"
  },
  "TenantResolver": {
    "Domain": "{0}.localhost:44355",
    "Web": "https://{0}.localhost:44316/",
    "Blazor": "https://{0}.localhost:44360/",
    "Validation": {
      "AuthServer": "https://localhost:44355/",
      "AuthServerWildcard": "https://{0}.localhost:44355/"
    }
  }
}

Blazor/appsetings.json:

  "App": {
    "SelfUrl": "https://localhost:44360",
    "DisablePII": false
  },
  "RemoteServices": {
    "Default": {
      "BaseUrl": "https://localhost:44325/"
    },
    "AbpAccountPublic": {
      "BaseUrl": "https://localhost:44355/"
    }
  },
  "Redis": {
    "Configuration": "127.0.0.1"
  },
  "RabbitMQ": {
    "Connections": {
      "Default": {
        "HostName": "localhost"
      }
    },
    "EventBus": {
      "ClientName": "BlazorServer",
      "ExchangeName": "Beta01"
    }
  },
  "AuthServer": {
    "Authority": "https://localhost:44355",
    "RequireHttpsMetadata": true,
    "ClientId": "Beta01_BlazorServer",
    "ClientSecret": "1q2w3e*"
  },
  "StringEncryption": {
    "DefaultPassPhrase": "mhvLo8IhGumjXM6Z"
  },
  "TenantResolver": {
    "Domain": "{0}.localhost:44360",
    "Validation": {
      "AuthServer": "https://localhost:44355/",
      "AuthServerWildcard": "https://{0}.localhost:44355/"
    },
    "UrlToReplace": "localhost"
  }
}

DbMigrator/appsettings.json:

  "ConnectionStrings": {
    "Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=Beta01-Personal;Trusted_Connection=True;TrustServerCertificate=true"
  },
  "Redis": {
    "Configuration": "127.0.0.1"
  },
  "OpenIddict": {
    "Applications": {
      "Beta01_Web_Public": {
        "ClientId": "Beta01_Web_Public",
        "ClientSecret": "1q2w3e*",
        "RootUrl": "https://localhost:44316"
      },
      "Beta01_App": {
        "ClientId": "Beta01_App"      },
      "Beta01_BlazorServer": {
        "ClientId": "Beta01_BlazorServer",
        "ClientSecret": "1q2w3e*",
        "RootUrl": "https://localhost:44360"
      },
      "Beta01_Swagger": {
        "ClientId": "Beta01_Swagger",
        "RootUrl": "https://localhost:44325/"
      }
    }
  }
}

HttpApi.Host/appsettings.json

  "App": {
    "SelfUrl": "https://localhost:44325",
    "MVCPublicUrl": "https://localhost:44316",
    "CorsOrigins": "https://*.Beta01.com",
    "DisablePII": false,
    "HealthCheckUrl": "/health-status"
  },
  "ConnectionStrings": {
    "Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=Beta01-Personal;Trusted_Connection=True;TrustServerCertificate=true"
  },
  "Redis": {
    "Configuration": "127.0.0.1"
  },
  "RabbitMQ": {
    "Connections": {
      "Default": {
        "HostName": "localhost"
      }
    },
    "EventBus": {
      "ClientName": "HttpApiHost",
      "ExchangeName": "Beta01"
    }
  },
  "AuthServer": {
    "Authority": "https://localhost:44355",
    "RequireHttpsMetadata": true,
    "MetaAddress": "https://localhost:44355",
    "SwaggerClientId": "Beta01_Swagger"
  },
  "StringEncryption": {
    "DefaultPassPhrase": "mhvLo8IhGumjXM6Z"
  },
  "TenantResolver": {
    "Domain": "{0}.localhost:44325",
    "Validation": {
      "AuthServer": "https://localhost:44355/",
      "AuthServerWildcard": "https://{0}.localhost:44355/"
    }
  }
}

WebPublic/appsettings.json:

  "App": {
    "SelfUrl": "https://localhost:44316",
    "DisablePII": false
  },
  "Redis": {
    "Configuration": "127.0.0.1"
  },
  "RemoteServices": {
    "Default": {
      "BaseUrl": "https://localhost:44325/"
    },
    "AbpAccountPublic": {
      "BaseUrl": "https://localhost:44355/"
    }
  },
  "AuthServer": {
    "Authority": "https://localhost:44355",
    "RequireHttpsMetadata": true,
    "ClientId": "Beta01_Web_Public",
    "ClientSecret": "1q2w3e*"
  },
  "TenantResolver": {
    "Domain": "{0}.localhost:44316",
    "Validation": {
      "AuthServer": "https://localhost:44355/",
      "AuthServerWildcard": "https://{0}.localhost:44355/"
    },
    "UrlToReplace": "localhost"
  }
}

Can someone help me?

@caiocollete
Copy link
Author

These "TenantResolver" is for use in BlazorModules.cs, HttpApi.HostModules.cs, AuthServerModule.cs and WebPublicModule.cs, like
configuration["TenantResolver:Domain"]

@caiocollete
Copy link
Author

   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.InjectNewHttp2ConnectionAsync(QueueItem queueItem)
   at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.Connections.Client.Internal.AccessTokenHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.Connections.Client.Internal.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
   at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.NegotiateAsync(Uri url, HttpClient httpClient, ILogger logger, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.GetNegotiationResponseAsync(Uri uri, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.SelectAndStartTransport(TransferFormat transferFormat, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsyncCore(TransferFormat transferFormat, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsync(TransferFormat transferFormat, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.ConnectAsync(EndPoint endPoint, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.ConnectAsync(EndPoint endPoint, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncCore(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncInner(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsync(CancellationToken cancellationToken)
   at Volo.Chat.Blazor.Components.MessagesToolbarItem.OnInitializedAsync()
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
   at Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.<WaitForNonStreamingPendingTasks>g__Execute|43_0()
   at Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.WaitForResultReady(Boolean waitForQuiescence, PrerenderedComponentHtmlContent result)
   at Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.RenderEndpointComponent(HttpContext httpContext, Type rootComponentType, ParameterView parameters, Boolean waitForQuiescence)
   at Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context)
   at Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context)
   at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c.<<InvokeAsync>b__10_0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Builder.ServerRazorComponentsEndpointConventionBuilderExtensions.<>c__DisplayClass1_1.<<AddInteractiveServerRenderMode>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Volo.Abp.AspNetCore.Serilog.AbpSerilogMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Volo.Abp.AspNetCore.Security.Claims.AbpDynamicClaimsMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Volo.Abp.AspNetCore.Security.AbpSecurityHeadersMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Volo.Abp.Studio.Client.AspNetCore.AbpStudioMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Volo.Abp.Studio.Client.AspNetCore.AbpStudioMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Volo.Abp.Studio.Client.AspNetCore.AbpStudioMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()

@caiocollete
Copy link
Author

My solution configuration:

  • Template: app
  • Created ABP Studio Version: 0.9.22
  • Current ABP Studio Version: 0.9.22
  • Tiered: Yes
  • Multi-Tenancy: Yes
  • UI Framework: blazor-server
  • Theme: leptonx
  • Theme Style: system
  • Run Install Libs: Yes
  • Database Provider: ef
  • Database Management System: sqlserver
  • Separate Tenant Schema: Yes
  • Create Initial Migration: Yes
  • Run Db Migrator: Yes
  • Mobile Framework: none
  • Public Website: Yes
  • Include Tests: Yes
  • Kubernetes Configuration: No
  • Distributed Event Bus: rabbitmq
  • Use Local References: No
  • Optional Modules:
    • GDPR
    • FileManagement
    • TextTemplateManagement
    • LanguageManagement
    • AuditLogging
    • Chat
    • OpenIddictAdmin

@maliming
Copy link
Member

maliming commented Feb 1, 2025

Your SSL certificate is invalid.

You can try to use getabp.net(127.0.0.1) as a domain and use getabp.net.pfx as an SSL certificate.

Type Domain Name IP Address
A getabp.net 127.0.0.1

@caiocollete
Copy link
Author

ok, thanks, where I can find this certificate?

@maliming
Copy link
Member

maliming commented Feb 2, 2025

@caiocollete
Copy link
Author

After changing all "localhost" to "getabp.net" and running DbMigrator again, the same error remains.

@caiocollete
Copy link
Author

My AuthServerModule:

 PreConfigure<AbpOpenIddictWildcardDomainOptions>(options =>
        {
            options.EnableWildcardDomainSupport = true;
            options.WildcardDomainsFormat.Add(configuration["TenantResolver:Web"]); // web
            options.WildcardDomainsFormat.Add(configuration["TenantResolver:Blazor"]); // blazor
        });
Configure<AbpTenantResolveOptions>(options =>
        {
            options.AddDomainTenantResolver(configuration["TenantResolver:Domain"]);
        });
        
        Configure<OpenIddictServerOptions>(options =>
        {
            options.TokenValidationParameters.IssuerValidator = TokenWildcardIssuerValidator.IssuerValidator;
            options.TokenValidationParameters.ValidIssuers = new[]
            {
                configuration["TenantResolver:Validation:AuthServer"],
                configuration["TenantResolver:Validation:AuthServerWildcard"]
            };
        });

My BlazorModule:

        {
            options.AddDomainTenantResolver(configuration["TenantResolver:Domain"]);
        });
            .AddAbpOpenIdConnect("oidc", options =>
            {
                options.Authority = configuration["AuthServer:Authority"];
                options.RequireHttpsMetadata = configuration.GetValue<bool>("AuthServer:RequireHttpsMetadata");
                options.ResponseType = OpenIdConnectResponseType.CodeIdToken;

                options.ClientId = configuration["AuthServer:ClientId"];
                options.ClientSecret = configuration["AuthServer:ClientSecret"];

                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;

                options.Scope.Add("roles");
                options.Scope.Add("email");
                options.Scope.Add("phone");
                options.Scope.Add("Beta01");
                
                options.Events.OnRedirectToIdentityProviderForSignOut = redirectContext =>
                {
                    var currentTenant = redirectContext.HttpContext.RequestServices.GetRequiredService<ICurrentTenant>();
                    var urlToReplace = configuration["TenantResolver:UrlToReplace"];
                    {
                        redirectContext.ProtocolMessage.IssuerAddress =
                            redirectContext.ProtocolMessage.IssuerAddress.Replace(urlToReplace,
                                $"{currentTenant.Name}.{urlToReplace}");
                    }

                    return Task.CompletedTask;
                };
            
                options.Events.OnRedirectToIdentityProvider = options.Events.OnRedirectToIdentityProviderForSignOut;

                options.TokenValidationParameters.IssuerValidator = TokenWildcardIssuerValidator.IssuerValidator;
                options.TokenValidationParameters.ValidIssuers = new[]
                {
                    configuration["TenantResolver:Validation:AuthServer"],
                    configuration["TenantResolver:Validation:AuthServerWildcard"]
                };
            });

My HttpApi.Host:

        Configure<AbpTenantResolveOptions>(options =>
        {
            options.AddDomainTenantResolver(configuration["TenantResolver:Domain"]);
        });

My Web.Public:

        Configure<AbpTenantResolveOptions>(options =>
        {
            options.AddDomainTenantResolver(configuration["TenantResolver:Domain"]);
        });
        .AddAbpOpenIdConnect("oidc", options =>
        {
            options.Authority = configuration["AuthServer:Authority"];
            options.RequireHttpsMetadata = configuration.GetValue<bool>("AuthServer:RequireHttpsMetadata");
            options.ResponseType = OpenIdConnectResponseType.CodeIdToken;

            options.ClientId = configuration["AuthServer:ClientId"];
            options.ClientSecret = configuration["AuthServer:ClientSecret"];

            options.SaveTokens = true;
            options.GetClaimsFromUserInfoEndpoint = true;

            options.Scope.Add("roles");
            options.Scope.Add("email");
            options.Scope.Add("phone");
            options.Scope.Add("Beta01");
            
            options.Events.OnRedirectToIdentityProviderForSignOut = redirectContext =>
            {
                var currentTenant = redirectContext.HttpContext.RequestServices.GetRequiredService<ICurrentTenant>();
                var urlToReplace = configuration["TenantResolver:UrlToReplace"];
                if (currentTenant.IsAvailable)
                {
                    redirectContext.ProtocolMessage.IssuerAddress =
                        redirectContext.ProtocolMessage.IssuerAddress.Replace(urlToReplace,
                            $"{currentTenant.Name}.{urlToReplace}");
                }

                return Task.CompletedTask;
            };
            
            options.Events.OnRedirectToIdentityProvider = options.Events.OnRedirectToIdentityProviderForSignOut;

            options.TokenValidationParameters.IssuerValidator = TokenWildcardIssuerValidator.IssuerValidator;
            options.TokenValidationParameters.ValidIssuers = new[]
            {
                configuration["TenantResolver:Validation:AuthServer"],
                configuration["TenantResolver:Validation:AuthServerWildcard"]
            };
        });

@maliming
Copy link
Member

maliming commented Feb 3, 2025

You can check the sample code and compare it with yours.

Sample code works well with SSL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants