Skip to main content

Diagnostic

Si vous avez l'erreur suivante 'main.d611e830ffe65f07.js:1 error validating authorization_endpoint in discovery document' :

image.png

Vérifier les URLs dans le fichier openid-configuration accessible à l'URL api-staging.societaire.cam.nc/.well-known/openid-configuration :

{
"issuer": "https://api-staging.societaire.cam.nc/",
"authorization_endpoint": "http://api-staging.societaire.cam.nc/connect/authorize",
"token_endpoint": "http://api-staging.societaire.cam.nc/connect/token",
"introspection_endpoint": "http://api-staging.societaire.cam.nc/connect/introspect",
"end_session_endpoint": "http://api-staging.societaire.cam.nc/connect/endsession",
"revocation_endpoint": "http://api-staging.societaire.cam.nc/connect/revocat",
"userinfo_endpoint": "http://api-staging.societaire.cam.nc/connect/userinfo",
"device_authorization_endpoint": "http://api-staging.societaire.cam.nc/device",
"pushed_authorization_request_endpoint": "http://api-staging.societaire.cam.nc/connect/par",
"jwks_uri": "http://api-staging.societaire.cam.nc/.well-known/jwks",
"grant_types_supported": [
"authorization_code",
"implicit",
"password",
"client_credentials",
...

Les URLs sont en HTTP et non en HTTPS, donc non accessibles derrière le reverse proxy.

Résolutions

Principalement inspiré de "Error retrieving discovery document: Endpoint does not use HTTPS: http://authserver.mydomain.dev/connect/authorize", #9849 | Support | ABP.IO mais aussi merci à Sonnet 4.0 !

Voici les modifications apportées dans le code :

  1. S'assure qur le issuer est bien en HTTPS dans la configuration :
const oAuthConfig = {
  issuer: 'https://api.societaire.cam.nc/',
...
  1. Modification du fichier NC.CAM.App.PortailClients.HttpApi.Host/PortailClientsHttpApiHostModule.cs :
            PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
            {
                serverBuilder.AddProductionEncryptionAndSigningCertificate("openiddict.pfx", configuration["AuthServer:CertificatePassPhrase"]!);
                serverBuilder.SetIssuer(new Uri(configuration["AuthServer:Authority"]!));

                // Force HTTPS pour tous les endpoints en production (résout le problème des URLs HTTP)
                serverBuilder.Configure(options =>
                {
                    options.UseReferenceAccessTokens = false;
                    options.DisableAccessTokenEncryption = false;
                });
            });
...
public override void ConfigureServices(ServiceConfigurationContext context)
    {
...

        // Configuration des ForwardedHeaders pour les environnements avec reverse proxy (DigitalOcean App Platform)
        ConfigureForwardedHeaders(context, configuration, hostingEnvironment);

        ConfigureAuthentication(context);
...
    }

private void ConfigureForwardedHeaders(ServiceConfigurationContext context, IConfiguration configuration, IWebHostEnvironment hostingEnvironment)
    {
        context.Services.Configure<ForwardedHeadersOptions>(options =>
        {
            // Configuration pour les environnements avec reverse proxy (DigitalOcean App Platform, nginx, etc.)
            options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | 
                                     ForwardedHeaders.XForwardedProto | 
                                     ForwardedHeaders.XForwardedHost;

            if (!hostingEnvironment.IsDevelopment())
            {
                // En production, faire confiance aux proxies de DigitalOcean App Platform
                options.KnownNetworks.Clear();
                options.KnownProxies.Clear();
                // Configuration spécifique pour DigitalOcean App Platform
                //options.ForwardLimit = 2; // Permet jusqu'à 2 proxies dans la chaîne
                options.RequireHeaderSymmetry = false;
                // Headers personnalisés utilisés par DigitalOcean
                options.ForwardedForHeaderName = "X-Forwarded-For";
                options.ForwardedProtoHeaderName = "X-Forwarded-Proto";
                options.ForwardedHostHeaderName = "X-Forwarded-Host";
                options.OriginalForHeaderName = "X-Original-For";
                options.OriginalProtoHeaderName = "X-Original-Proto";
                options.OriginalHostHeaderName = "X-Original-Host";
            }
            else
            {
                // En développement, configuration plus permissive pour le debugging
                options.ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedFor;
            }
        });
    }
...
public override void OnApplicationInitialization(ApplicationInitializationContext context)
    {
        var app = context.GetApplicationBuilder();
        var env = context.GetEnvironment();

        // IMPORTANT: UseForwardedHeaders doit être appelé très tôt dans le pipeline
        // avant tout middleware qui utilise Request.Scheme, Request.Host, ou Request.PathBase
        app.UseForwardedHeaders();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
...

Autres documentations

Quelques pistes pour plus tard :