Partage via


Configurez des points de terminaison pour le serveur web ASP.NET Core Kestrel

Note

Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 8 de cet article.

Avertissement

Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la Stratégie de prise en charge de .NET et .NET Core. Pour la version actuelle, consultez la version .NET 8 de cet article.

Important

Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.

Pour la version actuelle, consultez la version .NET 8 de cet article.

Remarque

Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 8 de cet article.

Avertissement

Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la Stratégie de prise en charge de .NET et .NET Core. Pour la version actuelle, consultez la version .NET 8 de cet article.

Important

Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.

Pour la version actuelle, consultez la version .NET 8 de cet article.

Les points de terminaison Kestrel fournissent l’infrastructure pour écouter les requêtes entrantes et les router vers le middleware approprié. Un point de terminaison est défini par la combinaison d’une adresse et d’un protocole.

  • L’adresse spécifie l’interface réseau sur laquelle le serveur est à l’écoute des requêtes entrantes, comme un port TCP.
  • Le protocole spécifie la communication entre le client et le serveur, comme HTTP/1.1, HTTP/2 ou HTTP/3.
  • Un point de terminaison peut être sécurisé à l’aide du schéma d’URL https ou de la méthode UseHttps.

Les points de terminaison peuvent être configurés avec des URL, JSON dans appsettings.json et dans le code. Cet article explique comment utiliser chaque option pour configurer un point de terminaison :

Point de terminaison par défaut.

Les nouveaux projets ASP.NET Core sont configurés pour être liés à un port HTTP aléatoire compris entre 5000 et 5300 et à un port HTTPS aléatoire compris entre 7000 et 7300. Les ports sélectionnés sont stockés dans le fichier généré Properties/launchSettings.json et peuvent être modifiés par le développeur. Le fichier launchSetting.json est utilisé uniquement en développement local.

S’il n’existe aucune configuration de point de terminaison, alors Kestrel se lie à http://localhost:5000.

Configuration des points de terminaison

Les points de terminaison Kestrel écoutent les connexions entrantes. Lorsqu’un point de terminaison est créé, il doit être configuré avec l’adresse qu’il écoutera. En règle générale, il s’agit d’une adresse TCP et d’un numéro de port.

Il existe plusieurs options pour configurer des points de terminaison :

Configurer des points de terminaison avec les URL

Les sections suivantes expliquent comment configurer des points de terminaison à l’aide des :

  • La variable d’environnement ASPNETCORE_URLS.
  • L’argument de ligne de commande --urls.
  • La clé de configuration d’hôte urls.
  • La méthode d’extension UseUrls.
  • Propriété WebApplication.Urls.

Formats d’URL

Les URL indiquent les adresses IP ou de l’hôte avec les ports et les protocoles que le serveur doit écouter. Le port peut être omis s’il s’agit de la valeur par défaut du protocole (généralement 80 et 443). Les URL peuvent être dans l'un des formats suivants.

  • Adresse IPv4 avec numéro de port

    http://65.55.39.10:80/
    

    0.0.0.0 est un cas spécial qui se lie à toutes les adresses IPv4.

  • Adresse IPv6 avec numéro de port

    http://[0:0:0:0:0:ffff:4137:270a]:80/
    

    [::] est l’équivalent IPv6 de 0.0.0.0 dans IPv4.

  • Hôte générique avec numéro de port

    http://contoso.com:80/
    http://*:80/
    

    Tout ce qui n’est pas reconnu comme une adresse IP valide ou localhost est traité comme un caractère générique qui se lie à toutes les adresses IPv4 et IPv6. Certaines personnes préfèrent utiliser * ou + pour être plus explicites. Pour lier différents noms d’hôte à différentes applications ASP.NET Core sur le même port, utilisez HTTP.sys ou un serveur proxy inverse.

    Les exemples de serveur proxy inverse incluent IIS, YARP, Nginx et Apache.

  • Nom de l’hôte localhost avec numéro de port ou adresse IP de bouclage avec numéro de port

    http://localhost:5000/
    http://127.0.0.1:5000/
    http://[::1]:5000/
    

    Quand localhost est spécifié, Kestrel tente de se lier aux interfaces de bouclage IPv4 et IPv6. Si le port requis est en cours d’utilisation par un autre service sur l’une des interfaces de bouclage, Kestrel ne démarre pas. Si l’une des interfaces de bouclage n’est pas disponible pour une raison quelconque (généralement du fait de la non-prise en charge d’IPv6), Kestrel journalise un avertissement.

Plusieurs préfixes d’URL peuvent être spécifiés à l’aide d’un délimiteur point-virgule (;) :

http://*:5000;http://localhost:5001;https://hostname:5002

Pour plus d’informations, consultez Remplacer la configuration.

Préfixes d’URL HTTPS

Les préfixes d’URL HTTPS peuvent être utilisés pour définir des points de terminaison uniquement si un certificat par défaut est fourni dans la configuration du point de terminaison HTTPS. Par exemple, utilisez la configuration KestrelServerOptions ou un fichier de configuration, comme indiqué plus loin dans cet article.

Pour plus d’informations, consultez Configurer HTTPS.

Spécifier uniquement des ports

Les applications et les conteneurs ne reçoivent souvent qu’un port à écouter, comme le port 80, sans contraintes supplémentaires telles que l’hôte ou le chemin d’accès. HTTP_PORTS et HTTPS_PORTS sont des clés de configuration qui spécifient les ports d’écoute pour les serveurs Kestrel et HTTP.sys. Ces clés peuvent être spécifiées en tant que variables d’environnement définies avec les préfixes DOTNET_ ou ASPNETCORE_, ou spécifiées directement par le biais d’une autre entrée de configuration, telle que appsettings.json. Il s’agit d’une liste délimitée par des points-virgules de valeurs de port, comme illustré dans l’exemple suivant :

ASPNETCORE_HTTP_PORTS=80;8080
ASPNETCORE_HTTPS_PORTS=443;8081

L’exemple précédent est abrégé pour la configuration suivante, qui spécifie le schéma (HTTP ou HTTPS) et tout hôte ou adresse IP.

ASPNETCORE_URLS=http://*:80/;http://*:8080/;https://*:443/;https://*:8081/

Les clés de configuration HTTP_PORTS et HTTPS_PORTS sont prioritaires et sont remplacées par des URL ou des valeurs fournies directement dans le code. Les certificats doivent toujours être configurés séparément via des mécanismes spécifiques au serveur pour HTTPS.

Configurer des points de terminaison dans appsettings.json

Kestrel peut charger des points de terminaison à partir d’une instance IConfiguration. Par défaut, la configuration Kestrel est chargée depuis la section Kestrel et les points de terminaison sont configurés dans Kestrel:Endpoints :

{
  "Kestrel": {
    "Endpoints": {
      "MyHttpEndpoint": {
        "Url": "http://localhost:8080"
      }
    }
  }
}

L’exemple précédent :

  • Utilise appsettings.json comme source de configuration. Toutefois, toute source IConfiguration peut être utilisée.
  • Ajoute un point de terminaison nommé MyHttpEndpoint sur le port 8080.

Pour plus d’informations sur la configuration des points de terminaison avec JSON, consultez les sections ultérieures de cet article qui traitent de la configuration HTTPS et de la configuration des protocoles HTTP dans appsettings.json.

Recharger des points de terminaison depuis la configuration

Recharger la configuration du point de terminaison lorsque la source de configuration change est activé par défaut. Cela peut être désactivé à l’aide de KestrelServerOptions.Configure(IConfiguration, Boolean).

Si un changement est signalé, les étapes suivantes sont effectuées :

  • La nouvelle configuration est comparée à l’ancienne, et aucun point de terminaison sans modification de configuration n’est modifié.
  • Les points de terminaison supprimés ou modifiés ont 5 secondes pour terminer le traitement des requêtes et s’arrêter.
  • Les points de terminaison nouveaux ou modifiés sont démarrés.

Les clients qui se connectent à un point de terminaison modifié peuvent être déconnectés ou refusés pendant le redémarrage du point de terminaison.

ChargeurDeConfiguration

KestrelServerOptions.Configure retourne un KestrelConfigurationLoader. Méthode Endpoint(String, Action<EndpointConfiguration>) du chargeur qui peut être utilisée pour compléter les paramètres d’un point de terminaison configuré :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    var kestrelSection = context.Configuration.GetSection("Kestrel");

    serverOptions.Configure(kestrelSection)
        .Endpoint("HTTPS", listenOptions =>
        {
            // ...
        });
});

Vous pouvez accéder directement à KestrelServerOptions.ConfigurationLoader pour continuer l’itération sur le chargeur existant, comme celui fourni par WebApplicationBuilder.WebHost.

  • La section de configuration pour chaque point de terminaison est disponible sur les options de la méthode Endpoint, ce qui permet de lire les paramètres personnalisés.
  • KestrelServerOptions.Configure(IConfiguration) peut être appelé plusieurs fois, mais seule la dernière configuration est utilisée, sauf si Load est explicitement appelé sur des instances antérieures. L’hôte par défaut n’appelle pas Load, sa section de configuration par défaut peut donc être remplacée.
  • KestrelConfigurationLoader met en miroir la famille Listen d’API à partir de KestrelServerOptions en tant que surcharges de Endpoint, de sorte que les points de terminaison de code et de configuration peuvent être configurés au même endroit. Ces surcharges n’utilisent pas de noms et consomment seulement les paramètres par défaut de la configuration.

Configurer des points de terminaison dans le code

KestrelServerOptions fournit des méthodes pour configurer des points de terminaison dans le code :

Quand les API Listen et UseUrls sont utilisées simultanément, les points de terminaison Listen remplacent les points de terminaison UseUrls.

Lier à un socket TCP

Les méthodes Listen, ListenLocalhost et ListenAnyIP se lient à un socket TCP :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

L’exemple précédent :

  • Configure les points de terminaison qui écoutent sur les ports 5000 et 5001.
  • Configure HTTPS pour un point de terminaison avec la méthode d’extension UseHttps sur ListenOptions. Pour plus d’informations, consultez Configurer HTTPS dans le code.

Pour créer des certificats auto-signés sous Windows, vous pouvez utiliser l’applet de commande PowerShell New-SelfSignedCertificate. Pour obtenir un exemple non pris en charge, consultez UpdateIISExpressSSLForChrome.ps1.

OpenSSL permet de créer des certificats sous macOS, Linux et Windows.

Lier à un socket Unix

Écoutez sur un socket Unix avec ListenUnixSocket pour améliorer les performances avec Nginx, comme illustré dans cet exemple :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
  • Dans le fichier de configuration Nginx, définissez l’entrée server>location>proxy_pass sur http://unix:/tmp/{KESTREL SOCKET}:/;. {KESTREL SOCKET} est le nom du socket fourni à ListenUnixSocket (par exemple, kestrel-test.sock dans l’exemple précédent).
  • Vérifiez que le socket est accessible en écriture par Nginx (par exemple, chmod go+w /tmp/kestrel-test.sock).

Configurer les valeurs par défaut des points de terminaison

ConfigureEndpointDefaults(Action<ListenOptions>) spécifie la configuration qui s’exécute pour chaque point de terminaison spécifié. L’appel de ConfigureEndpointDefaults à plusieurs reprises remplace la configuration précédente.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });
});

Note

Les points de terminaison créés en appelant Listen avant d’appeler ConfigureEndpointDefaults n’ont pas les valeurs par défaut appliquées.

Liaison de port dynamique

Si le numéro de port 0 est spécifié, Kestrel se lie dynamiquement à un port disponible. L’exemple suivant montre comment déterminer le port auquel Kestrel se lie au moment de l’exécution :

app.Run(async (context) =>
{
    var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();

    if (serverAddressFeature is not null)
    {
        var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);

        // ...
    }
});

La liaison dynamique d’un port n’est pas disponible dans certaines situations :

Configurer HTTPS

Kestrel prend en charge la sécurisation des points de terminaison avec HTTPS. Les données envoyées via HTTPS sont chiffrées à l’aide du protocole TLS (Transport Layer Security) pour augmenter la sécurité des données transférées entre le client et le serveur.

HTTPS nécessite un certificat TLS. Le certificat TLS est stocké sur le serveur et Kestrel est configuré pour l’utiliser. Une application peut utiliser le certificat de développement HTTPS ASP.NET Core dans un environnement de développement local. Le certificat de développement n’est pas installé dans les environnements non développés. En production, un certificat TLS doit être configuré explicitement. Au minimum, un certificat par défaut doit être fourni.

La façon dont HTTPS et le certificat TLS sont configurés dépend de la façon dont les points de terminaison sont configurés :

Configurer HTTPS dans appsettings.json

Un schéma de configuration des paramètres d’application HTTPS par défaut est disponible pour Kestrel. Configurez plusieurs points de terminaison, notamment les URL et les certificats à utiliser, à partir d’un fichier sur disque ou d’un magasin de certificats.

Tout point de terminaison HTTPS qui ne spécifie pas de certificat (HttpsDefaultCert dans l’exemple qui suit) revient au certificat défini sous Certificates:Default ou au certificat de développement.

L’exemple suivant concerne appsettings.json, mais toute source de configuration peut être utilisée :

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, le mot de passe du certificat est stocké en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe du certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

Notes de schéma

  • Les noms des points de terminaison ne sont pas sensibles à la casse. Par exemple, HTTPS and Https sont équivalentes.
  • Le paramètre Url est obligatoire pour chaque point de terminaison. Le format de ce paramètre est le même que celui du paramètre de configuration Urls du plus haut niveau, sauf qu’il est limité à une seule valeur. Consultez Formats d’URL plus haut dans cet article.
  • Ces points de terminaison remplacent ceux qui sont définis dans la configuration Urls de niveau supérieur, plutôt que de s’y ajouter. Les points de terminaison définis dans le code via Listen sont cumulatifs avec les points de terminaison définis dans la section de configuration.
  • La section Certificate est facultative. Si la section Certificate n’est pas spécifiée, les valeurs par défaut définies dans Certificates:Default sont utilisées. Si aucune valeur par défaut n’est disponible, le certificat de développement est utilisé. S’il n’existe aucune valeur par défaut et que le certificat de développement n’est pas présent, le serveur lève une exception et ne parvient pas à démarrer.
  • La section Certificate prend en charge plusieurs sources de certificat.
  • Vous pouvez définir tout nombre de points de terminaison dans Configuration, pour autant qu’ils ne provoquent pas de conflits de port.

Sources de certificat

Les nœuds de certificat peuvent être configurés pour charger des certificats à partir d’un certain nombre de sources :

  • Path et Password pour charger des fichiers .pfx.
  • Path, KeyPath et Password pour charger des fichiers .pem/.crt et .key.
  • Subject et Store pour charger à partir du magasin de certificats.

Par exemple, le certificat Certificates:Default peut être spécifié comme suit :

"Default": {
  "Subject": "<subject; required>",
  "Store": "<cert store; required>",
  "Location": "<location; defaults to CurrentUser>",
  "AllowInvalid": "<true or false; defaults to false>"
}

Configurer des certificats client dans appsettings.json

ClientCertificateMode est utilisé pour configurer le comportement du certificat client.

{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "ClientCertificateMode": "AllowCertificate",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, le mot de passe du certificat est stocké en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe du certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

La valeur par défaut est ClientCertificateMode.NoCertificate, où Kestrel ne demande ni n’exige un certificat de la part du client.

Pour plus d’informations, consultez Configurer l’authentification par certificat dans ASP.NET Core.

Configurer des protocoles SSL/TLS dans appsettings.json

Les protocoles SSL sont des protocoles utilisés pour chiffrer et déchiffrer le trafic entre deux homologues, généralement un client et un serveur.

{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "SslProtocols": ["Tls12", "Tls13"],
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, le mot de passe du certificat est stocké en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe du certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

La valeur par défaut, SslProtocols.None, fait en sorte que Kestrel utilise les valeurs par défaut du système d’exploitation pour choisir le meilleur protocole. Sauf si vous avez une raison particulière de sélectionner un protocole, utilisez la valeur par défaut.

Configurer HTTPS dans le code

Lorsque vous utilisez l’API Listen, la méthode d’extension UseHttps sur ListenOptions est disponible pour configurer HTTPS.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

Paramètres de ListenOptions.UseHttps :

  • filename est le chemin et le nom d’un fichier de certificat, relatif au répertoire qui contient les fichiers de contenu de l’application.
  • password est le mot de passe nécessaire pour accéder aux données du certificat X.509.
  • configureOptions est une Action pour configurer les HttpsConnectionAdapterOptions. Retourne l'ListenOptions.
  • storeName est le magasin de certificats à partir duquel charger le certificat.
  • subject est le nom du sujet du certificat.
  • allowInvalid indique si les certificats non valides doivent être considérés, comme les certificats auto-signés.
  • location est l’emplacement du magasin à partir duquel charger le certificat.
  • serverCertificate est le certificat X.509.

Pour obtenir la liste complète des surcharges UseHttps, consultez UseHttps.

Configurer des certificats client dans le code

ClientCertificateMode configure les exigences du certificat client.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    });
});

La valeur par défaut est NoCertificate, où Kestrel ne demande ni n’exige un certificat de la part du client.

Pour plus d’informations, consultez Configurer l’authentification par certificat dans ASP.NET Core.

Configurer les valeurs HTTPS par défaut dans le code

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) spécifie une configuration Action à exécuter pour chaque point de terminaison HTTPS. L’appel de ConfigureHttpsDefaults à plusieurs reprises remplace les instances Action précédentes par la dernière Action spécifiée.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

Note

Les points de terminaison créés en appelant Listen avant d’appeler ConfigureHttpsDefaults n’ont pas les valeurs par défaut appliquées.

Configurer des protocoles SSL/TLS dans le code

Les protocoles SSL sont des protocoles utilisés pour chiffrer et déchiffrer le trafic entre deux homologues, généralement un client et un serveur.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls13;
    });
});

Configurer le filtre de suites de chiffrement TLS dans le code

Sur Linux, CipherSuitesPolicy peut être utilisé pour filtrer les établissements de liaisons TLS par connexion :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.OnAuthenticate = (context, sslOptions) =>
        {
            sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
                new[]
                {
                    TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                    TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
                    // ...
                });
        };
    });
});

Configurer SNI (Indication du nom de serveur)

L’indication du nom de serveur (SNI, Server Name Indication) peut être utilisée pour héberger plusieurs domaines sur la même adresse IP et le même port. SNI peut être utilisé pour conserver des ressources en servant plusieurs sites depuis un serveur.

Pour que SNI fonctionne, le client envoie le nom d’hôte pour la session sécurisée au serveur pendant la négociation TLS afin que le serveur puisse fournir le certificat correct. Le client utilise le certificat fourni pour la communication chiffrée avec le serveur pendant la session sécurisée qui suit la négociation TLS.

Tous les sites web doivent s’exécuter sur la même instance Kestrel. Kestrel ne prend pas en charge le partage d’une adresse IP et d’un port entre plusieurs instances sans un proxy inverse.

L’Indication du nom du serveur peut être configurée de deux manières :

  • Configurez un mappage entre les noms d’hôtes et les options HTTPS dans Configuration. Par exemple, JSON dans le fichier appsettings.json.
  • Créez un point de terminaison dans le code et sélectionnez un certificat en utilisant le nom d’hôte avec le rappel ServerCertificateSelector.

Configurer SNI dans appsettings.json

Kestrel prend en charge l’indication du nom du serveur définie dans la configuration. Un point de terminaison peut être configuré avec un objet Sni qui contient un mappage entre les noms d’hôtes et les options HTTPS. Le nom d’hôte de la connexion est associé aux options et elles sont utilisées pour cette connexion.

La configuration suivante ajoute un point de terminaison nommé MySniEndpoint qui utilise l’indication du nom du serveur pour sélectionner les options HTTPS en fonction du nom d’hôte :

{
  "Kestrel": {
    "Endpoints": {
      "MySniEndpoint": {
        "Url": "https://*",
        "SslProtocols": ["Tls11", "Tls12"],
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": ["Tls11", "Tls12", "Tls13"],
            "Certificate": {
              "Subject": "<subject; required>",
              "Store": "<certificate store; required>",
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "<path to .pfx file>",
              "Password": "$CREDENTIAL_PLACEHOLDER$"
            }
          },
          "*": {
            // At least one subproperty needs to exist per SNI section or it
            // cannot be discovered via IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, le mot de passe du certificat est stocké en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe du certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

Options HTTPS qui peuvent être remplacées par l’indication du nom du serveur :

Le nom d’hôte prend en charge la correspondance de caractères génériques :

  • Correspondance exacte. Par exemples, a.example.org correspond à a.example.org.
  • Préfixe de caractère générique. S’il existe plusieurs correspondances de caractère générique, alors le modèle le plus long est choisi. Par exemple, *.example.org correspond à b.example.org et c.example.org.
  • Caractère générique complet. * correspond à tout le reste, y compris les clients qui n’utilisent pas l’indication du nom du serveur et n’envoient pas de nom d’hôte.

La configuration de l’indication du nom du serveur correspondante est appliquée au point de terminaison de la connexion, en remplaçant les valeurs sur le point de terminaison. Si une connexion ne correspond pas à un nom d’hôte SNI configuré, alors la connexion est refusée.

Configurer SNI avec du code

Kestrel prend en charge SNI avec plusieurs API de rappel :

  • ServerCertificateSelector
  • ServerOptionsSelectionCallback
  • TlsHandshakeCallbackOptions

SNI avec ServerCertificateSelector

Kestrel prend en charge l’indication du nom du serveur via le rappel ServerCertificateSelector. Le rappel est appelé une fois par connexion pour permettre à l’application d’inspecter le nom d’hôte et de sélectionner le certificat approprié :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var subExampleCert = CertificateLoader.LoadFromStoreCert(
                "sub.example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var certs = new Dictionary<string, X509Certificate2>(
                StringComparer.OrdinalIgnoreCase)
            {
                ["localhost"] = localhostCert,
                ["example.com"] = exampleCert,
                ["sub.example.com"] = subExampleCert
            };

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name is not null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

SNI avec ServerOptionsSelectionCallback

Kestrel prend en charge une configuration TLS dynamique supplémentaire via le rappel ServerOptionsSelectionCallback. Le rappel est appelé une fois par connexion pour permettre à l’application d’inspecter le nom d’hôte et de sélectionner le certificat et la configuration TLS appropriés. Les certificats par défaut et ConfigureHttpsDefaults ne sont pas utilisés avec ce rappel.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);

            listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
            {
                if (string.Equals(clientHelloInfo.ServerName, "localhost",
                    StringComparison.OrdinalIgnoreCase))
                {
                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = localhostCert,
                            // Different TLS requirements for this host
                            ClientCertificateRequired = true
                        });
                }

                return new ValueTask<SslServerAuthenticationOptions>(
                    new SslServerAuthenticationOptions
                    {
                        ServerCertificate = exampleCert
                    });
            }, state: null!);
        });
    });
});

SNI avec TlsHandshakeCallbackOptions

Kestrel prend en charge une configuration TLS dynamique supplémentaire via le rappel TlsHandshakeCallbackOptions.OnConnection. Le rappel est appelé une fois par connexion pour permettre à l’application d’inspecter le nom d’hôte et de sélectionner le certificat, la configuration TLS et d’autres options de serveur appropriés. Les certificats par défaut et ConfigureHttpsDefaults ne sont pas utilisés avec ce rappel.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);

            listenOptions.UseHttps(new TlsHandshakeCallbackOptions
            {
                OnConnection = context =>
                {
                    if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
                        StringComparison.OrdinalIgnoreCase))
                    {
                        // Different TLS requirements for this host
                        context.AllowDelayedClientCertificateNegotation = true;

                        return new ValueTask<SslServerAuthenticationOptions>(
                            new SslServerAuthenticationOptions
                            {
                                ServerCertificate = localhostCert
                            });
                    }

                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = exampleCert
                        });
                }
            });
        });
    });
});

Configurer des protocoles HTTP

Kestrel prend en charge toutes les versions HTTP couramment utilisées. Les points de terminaison peuvent être configurés pour prendre en charge différentes versions HTTP à l’aide de l’énumération HttpProtocols, qui spécifie les options de version HTTP disponibles.

TLS est nécessaire pour prendre en charge plus d’une version HTTP. Le protocole ALPN (Application-Layer Protocol Negotiation) d’établissement de liaison de la TLS est utilisé pour négocier le protocole de connexion entre le client et le serveur lorsqu’un point de terminaison prend en charge plusieurs protocoles.

Valeur HttpProtocols Protocole de connexion autorisé
Http1 HTTP/1.1 uniquement. Peut être utilisé avec ou sans TLS.
Http2 HTTP/2 uniquement. Peut être utilisé sans TLS, uniquement si le client prend en charge un mode de connaissance préalable (Prior Knowledge).
Http3 HTTP/3 uniquement. Nécessite TLS. Le client doit peut-être être configuré pour utiliser HTTP/3 uniquement.
Http1AndHttp2 HTTP/1.1 et HTTP/2. HTTP/2 nécessite que le client sélectionne HTTP/2 dans l’établissement d’une liaison TLS ALPN (Application-Layer Protocol Negotiation) ; sinon, la connexion est établie par défaut sur HTTP/1.1.
Http1AndHttp2AndHttp3 HTTP/1.1, HTTP/2 et HTTP/3. La première requête client utilise normalement HTTP/1.1 ou HTTP/2, et l’en-tête de alt-svc réponse invite le client à effectuer une mise à niveau vers HTTP/3. HTTP/2 et HTTP/3 nécessitent TLS ; sinon, la connexion par défaut est HTTP/1.1.

La valeur de protocole par défaut d’un point de terminaison est HttpProtocols.Http1AndHttp2.

Restrictions TLS pour HTTP/2 :

  • TLS version 1.2 ou ultérieure
  • Renégociation désactivée
  • Compression désactivée
  • Tailles minimales de l’échange de clé éphémère :
    • Diffie-Hellman à courbe elliptique (ECDHE) [RFC4492] : 224 bits minimum
    • Diffie-Hellman à champ fini (DHE) [TLS12] : 2048 bits minimum
  • Suite de chiffrement non interdite.

Prise en charge par défaut de TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] avec la courbe elliptique P-256 [FIPS186].

Configurer des protocoles HTTP dans appsettings.json

L’exemple appsettings.json suivant établit le protocole de connexion HTTP/1.1 pour un point de terminaison spécifique :

{
  "Kestrel": {
    "Endpoints": {
      "HttpsDefaultCert": {
        "Url": "https://localhost:5001",
        "Protocols": "Http1"
      }
    }
  }
}

Un protocole par défaut peut être configuré dans la section Kestrel:EndpointDefaults. L’exemple appsettings.json suivant établit HTTP/1.1 comme protocole de connexion par défaut pour tous les points de terminaison :

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1"
    }
  }
}

Les protocoles spécifiés dans le code remplacent les valeurs définies par configuration.

Configurer des protocoles HTTP dans le code

ListenOptions.Protocols est utilisé pour spécifier des protocoles avec l’énumération HttpProtocols.

L’exemple suivant configure un point de terminaison pour les connexions HTTP/1.1, HTTP/2 et HTTP/3 sur le port 8000. Les connexions sont sécurisées par TLS avec un certificat fourni :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
    });
});

Voir aussi

Les projets ASP.NET Core sont configurés pour être liés à un port HTTP aléatoire compris entre 5 000 et 5 300 et à un port HTTPS aléatoire compris entre 7 000 et 7 300. Cette configuration par défaut est spécifiée dans le fichier Properties/launchSettings.json généré et peut être remplacée. Si aucun port n’est spécifié, Kestrel est lié à http://localhost:5000.

Spécifiez les URL avec :

  • La variable d’environnement ASPNETCORE_URLS.
  • L’argument de ligne de commande --urls.
  • La clé de configuration d’hôte urls.
  • La méthode d’extension UseUrls.

La valeur fournie avec ces approches peut être un ou plusieurs points de terminaison HTTP et HTTPS (HTTPS si un certificat par défaut est disponible). Configurez la valeur sous forme de liste délimitée par des points-virgules (par exemple "Urls": "http://localhost:8000;http://localhost:8001").

Pour plus d’informations sur ces approches, voir URL de serveur et Remplacer la configuration.

Un certificat de développement est créé :

Le certificat de développement est disponible uniquement pour l’utilisateur qui génère le certificat. Certains navigateurs nécessitent l’autorisation explicite pour faire confiance au certificat de développement local.

Les modèles de projet configurent les applications pour qu’elles s’exécutent sur HTTPS par défaut et incluent la redirection HTTPS et la prise en charge HSTS.

Appelez les méthodes Listen ou ListenUnixSocket sur KestrelServerOptions pour configurer les préfixes et les ports d’URL pour Kestrel.

UseUrls, l’argument de ligne de commande --urls, la clé de configuration d’hôte urls et la variable d’environnement ASPNETCORE_URLS fonctionnent également, mais ils présentent les limitations indiquées plus loin dans cette section (un certificat par défaut doit être disponible pour la configuration du point de terminaison HTTPS).

ConfigurationKestrelServerOptions :

ConfigureEndpointDefaults

ConfigureEndpointDefaults(Action<ListenOptions>) spécifie une configuration Action à exécuter pour chaque point de terminaison spécifié. Le fait d’appeler ConfigureEndpointDefaults plusieurs fois remplace les Action précédents par le dernier Action spécifié :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });
});

Note

Les points de terminaison créés en appelant Listen avant d’appeler ConfigureEndpointDefaults n’ont pas les valeurs par défaut appliquées.

Configure(IConfiguration)

Permet à Kestrel de charger des points de terminaison à partir d’un IConfiguration. La configuration doit être étendue à la section de configuration pour Kestrel. La surcharge Configure(IConfiguration, bool) peut être utilisée pour activer le rechargement des points de terminaison lorsque la source de configuration change.

Par défaut, la configuration Kestrel est chargée à partir de la section Kestrel et le rechargement des modifications est activé :

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "Https": {
        "Url": "https://localhost:5001"
      }
    }
  }
}

Si la configuration de rechargement est activée et qu’une modification est signalée, les étapes suivantes sont suivies :

  • La nouvelle configuration est comparée à l’ancienne. Aucun point de terminaison sans modification de configuration n’est modifié.
  • Les points de terminaison supprimés ou modifiés ont 5 secondes pour terminer le traitement des requêtes et s’arrêter.
  • Les points de terminaison nouveaux ou modifiés sont démarrés.

Les clients qui se connectent à un point de terminaison modifié peuvent être déconnectés ou refusés pendant le redémarrage du point de terminaison.

ConfigureHttpsDefaults

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) spécifie une configuration Action à exécuter pour chaque point de terminaison HTTPS. Le fait d’appeler ConfigureHttpsDefaults plusieurs fois remplace les Actions précédentes par la dernière Action spécifiée.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

Note

Les points de terminaison créés en appelant Listen avant d’appeler ConfigureHttpsDefaults n’ont pas les valeurs par défaut appliquées.

ListenOptions.UseHttps

Configurez Kestrel pour utiliser HTTPS.

Extensions de ListenOptions.UseHttps :

  • UseHttps : configurez Kestrel pour utiliser HTTPS avec le certificat par défaut. Lève une exception si aucun certificat par défaut n’est configuré.
  • UseHttps(string fileName)
  • UseHttps(string fileName, string password)
  • UseHttps(string fileName, string password, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(StoreName storeName, string subject)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(X509Certificate2 serverCertificate)
  • UseHttps(X509Certificate2 serverCertificate, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(Action<HttpsConnectionAdapterOptions> configureOptions)

Paramètres de ListenOptions.UseHttps :

  • filename est le chemin et le nom d’un fichier de certificat, relatif au répertoire qui contient les fichiers de contenu de l’application.
  • password est le mot de passe nécessaire pour accéder aux données du certificat X.509.
  • configureOptions est une Action pour configurer les HttpsConnectionAdapterOptions. Retourne l'ListenOptions.
  • storeName est le magasin de certificats à partir duquel charger le certificat.
  • subject est le nom du sujet du certificat.
  • allowInvalid indique si les certificats non valides doivent être considérés, comme les certificats auto-signés.
  • location est l’emplacement du magasin à partir duquel charger le certificat.
  • serverCertificate est le certificat X.509.

En production, HTTPS doit être explicitement configuré. Au minimum, un certificat par défaut doit être fourni.

Si les certificats sont lus à partir du disque, par opposition à un Magasin de certificats Windows, le répertoire contenant doit disposer des autorisations appropriées pour empêcher l’accès non autorisé.

Configurations prises en charge décrites dans la suite :

  • Pas de configuration
  • Remplacer le certificat par défaut dans la configuration
  • Changer les valeurs par défaut dans le code

Pas de configuration

Kestrel écoute sur http://localhost:5000.

Remplacer le certificat par défaut dans la configuration

Un schéma de configuration des paramètres d’application HTTPS par défaut est disponible pour Kestrel. Configurez plusieurs points de terminaison, notamment les URL et les certificats à utiliser, à partir d’un fichier sur disque ou d’un magasin de certificats.

Dans l’exemple appsettings.json suivant :

  • Définissez AllowInvalid sur true pour permettre l’utilisation de certificats non valides (par exemple des certificats auto-signés).
  • Tout point de terminaison HTTPS qui ne spécifie pas de certificat (HttpsDefaultCert dans l’exemple qui suit) revient au certificat défini sous Certificates:Default ou au certificat de développement.
{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, les mots de passe de certificat sont stockés en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe de chaque certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

Notes de schéma :

  • Les noms des points de terminaison ne respectent pas la casse. Par exemple, HTTPS and Https sont équivalentes.
  • Le paramètre Url est obligatoire pour chaque point de terminaison. Le format de ce paramètre est le même que celui du paramètre de configuration Urls du plus haut niveau, sauf qu’il est limité à une seule valeur.
  • Ces points de terminaison remplacent ceux qui sont définis dans le paramètre de configuration Urls du plus haut niveau configuration, au lieu de s’y ajouter. Les points de terminaison définis dans le code via Listen sont cumulatifs avec les points de terminaison définis dans la section de configuration.
  • La section Certificate est facultative. Si la section Certificate n’est pas spécifiée, les valeurs par défaut définies dans Certificates:Default sont utilisées. Si aucune valeur par défaut n’est disponible, le certificat de développement est utilisé. S’il n’existe aucune valeur par défaut et que le certificat de développement n’est pas présent, le serveur lève une exception et ne parvient pas à démarrer.
  • La section Certificate prend en charge plusieurs sources de certificats.
  • Vous pouvez définir un nombre quelconque de points de terminaison Configuration, pour autant qu’ils ne provoquent pas de conflits de port.

Sources de certificat

Les nœuds de certificat peuvent être configurés pour charger des certificats à partir d’un certain nombre de sources :

  • Path et Password pour charger des fichiers .pfx.
  • Path, KeyPath et Password pour charger des fichiers .pem/.crt et .key.
  • Subject et Store pour charger à partir du magasin de certificats.

Par exemple, le certificat Certificates:Default peut être spécifié comme suit :

"Default": {
  "Subject": "<subject; required>",
  "Store": "<cert store; required>",
  "Location": "<location; defaults to CurrentUser>",
  "AllowInvalid": "<true or false; defaults to false>"
}

ChargeurDeConfiguration

Configure(IConfiguration) retourne un KestrelConfigurationLoader avec une méthode Endpoint(String, Action<EndpointConfiguration>) qui peut être utilisée pour compléter les paramètres d’un point de terminaison configuré :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    var kestrelSection = context.Configuration.GetSection("Kestrel");

    serverOptions.Configure(kestrelSection)
        .Endpoint("HTTPS", listenOptions =>
        {
            // ...
        });
});

Vous pouvez accéder directement à KestrelServerOptions.ConfigurationLoader pour continuer l’itération sur le chargeur existant, comme celui fourni par WebApplicationBuilder.WebHost.

  • La section de configuration pour chaque point de terminaison est disponible sur les options de la méthode Endpoint, ce qui permet de lire les paramètres personnalisés.
  • Plusieurs configurations peuvent être chargées en rappelant Configure(IConfiguration) avec une autre section. Seule la dernière configuration est utilisée, à moins que Load soit explicitement appelé sur les instances précédentes. Le métapackage n’appelle pas Load : sa section de configuration par défaut peut donc être remplacée.
  • KestrelConfigurationLoader reflète la famille d’API Listen de KestrelServerOptions sous forme de surcharges de Endpoint : le code et les points de terminaison de configuration peuvent donc être configurés au même emplacement. Ces surcharges n’utilisent pas de noms et consomment seulement les paramètres par défaut de la configuration.

Changer les valeurs par défaut dans le code

ConfigureEndpointDefaults et ConfigureHttpsDefaults peuvent être utilisés pour modifier les paramètres par défaut pour ListenOptions et HttpsConnectionAdapterOptions, notamment en remplaçant le certificat par défaut spécifié dans le scénario précédent. ConfigureEndpointDefaults et ConfigureHttpsDefaults doivent être appelés avant que des points de terminaison soient configurés.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });

    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

Configurez des points de terminaison à l’aide de l’Indication du nom du serveur

L’indication du nom de serveur (SNI, Server Name Indication) peut être utilisée pour héberger plusieurs domaines sur la même adresse IP et le même port. Pour que SNI fonctionne, le client envoie le nom d’hôte pour la session sécurisée au serveur pendant la négociation TLS afin que le serveur puisse fournir le certificat correct. Le client utilise le certificat fourni pour la communication chiffrée avec le serveur pendant la session sécurisée qui suit la négociation TLS.

L’Indication du nom du serveur peut être configurée de deux manières :

  • Créez un point de terminaison dans le code et sélectionnez un certificat en utilisant le nom d’hôte avec le rappel ServerCertificateSelector.
  • Configurez un mappage entre les noms d’hôtes et les options HTTPS dans Configuration. Par exemple, JSON dans le fichier appsettings.json.

SNI avec ServerCertificateSelector

Kestrel prend en charge l’indication du nom du serveur via le rappel ServerCertificateSelector. Le rappel est appelé une fois par connexion pour permettre à l’application d’inspecter le nom d’hôte et de sélectionner le certificat approprié :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var subExampleCert = CertificateLoader.LoadFromStoreCert(
                "sub.example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var certs = new Dictionary<string, X509Certificate2>(
                StringComparer.OrdinalIgnoreCase)
            {
                ["localhost"] = localhostCert,
                ["example.com"] = exampleCert,
                ["sub.example.com"] = subExampleCert
            };

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name is not null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

SNI avec ServerOptionsSelectionCallback

Kestrel prend en charge une configuration TLS dynamique supplémentaire via le rappel ServerOptionsSelectionCallback. Le rappel est appelé une fois par connexion pour permettre à l’application d’inspecter le nom d’hôte et de sélectionner le certificat et la configuration TLS appropriés. Les certificats par défaut et ConfigureHttpsDefaults ne sont pas utilisés avec ce rappel.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);

            listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
            {
                if (string.Equals(clientHelloInfo.ServerName, "localhost",
                    StringComparison.OrdinalIgnoreCase))
                {
                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = localhostCert,
                            // Different TLS requirements for this host
                            ClientCertificateRequired = true
                        });
                }

                return new ValueTask<SslServerAuthenticationOptions>(
                    new SslServerAuthenticationOptions
                    {
                        ServerCertificate = exampleCert
                    });
            }, state: null!);
        });
    });
});

SNI avec TlsHandshakeCallbackOptions

Kestrel prend en charge une configuration TLS dynamique supplémentaire via le rappel TlsHandshakeCallbackOptions.OnConnection. Le rappel est appelé une fois par connexion pour permettre à l’application d’inspecter le nom d’hôte et de sélectionner le certificat, la configuration TLS et d’autres options de serveur appropriés. Les certificats par défaut et ConfigureHttpsDefaults ne sont pas utilisés avec ce rappel.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);

            listenOptions.UseHttps(new TlsHandshakeCallbackOptions
            {
                OnConnection = context =>
                {
                    if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
                        StringComparison.OrdinalIgnoreCase))
                    {
                        // Different TLS requirements for this host
                        context.AllowDelayedClientCertificateNegotation = true;

                        return new ValueTask<SslServerAuthenticationOptions>(
                            new SslServerAuthenticationOptions
                            {
                                ServerCertificate = localhostCert
                            });
                    }

                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = exampleCert
                        });
                }
            });
        });
    });
});

SNI dans la configuration

Kestrel prend en charge l’indication du nom du serveur définie dans la configuration. Un point de terminaison peut être configuré avec un objet Sni qui contient un mappage entre les noms d’hôtes et les options HTTPS. Le nom d’hôte de la connexion est associé aux options et elles sont utilisées pour cette connexion.

La configuration suivante ajoute un point de terminaison nommé MySniEndpoint qui utilise l’indication du nom du serveur pour sélectionner les options HTTPS en fonction du nom d’hôte :

{
  "Kestrel": {
    "Endpoints": {
      "MySniEndpoint": {
        "Url": "https://*",
        "SslProtocols": ["Tls11", "Tls12"],
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": ["Tls11", "Tls12", "Tls13"],
            "Certificate": {
              "Subject": "<subject; required>",
              "Store": "<certificate store; required>",
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "<path to .pfx file>",
              "Password": "$CREDENTIAL_PLACEHOLDER$"
            }
          },
          "*": {
            // At least one subproperty needs to exist per SNI section or it
            // cannot be discovered via IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, les mots de passe de certificat sont stockés en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe de chaque certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

Options HTTPS qui peuvent être remplacées par l’indication du nom du serveur :

Le nom d’hôte prend en charge la correspondance de caractères génériques :

  • Correspondance exacte. Par exemples, a.example.org correspond à a.example.org.
  • Préfixe de caractère générique. S’il existe plusieurs correspondances de caractère générique, le modèle le plus long est choisi. Par exemple, *.example.org correspond à b.example.org et c.example.org.
  • Caractère générique complet. * correspond à tout le reste, y compris les clients qui n’utilisent pas l’indication du nom du serveur et n’envoient pas de nom d’hôte.

La configuration de l’indication du nom du serveur correspondante est appliquée au point de terminaison de la connexion, en remplaçant les valeurs sur le point de terminaison. Si une connexion ne correspond pas à un nom d’hôte de l’indication du nom du serveur configuré, la connexion est refusée.

Conditions requises pour l’indication du nom du serveur

Tous les sites web doivent s’exécuter sur la même instance Kestrel. Kestrel ne prend pas en charge le partage d’une adresse IP et d’un port entre plusieurs instances sans un proxy inverse.

Protocoles SSL/TLS

Les protocoles SSL sont des protocoles utilisés pour chiffrer et déchiffrer le trafic entre deux homologues, généralement un client et un serveur.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls13;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "SslProtocols": ["Tls12", "Tls13"],
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, le mot de passe du certificat est stocké en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe du certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

La valeur par défaut, SslProtocols.None, fait en sorte que Kestrel utilise les valeurs par défaut du système d’exploitation pour choisir le meilleur protocole. Sauf si vous avez une raison particulière de sélectionner un protocole, utilisez la valeur par défaut.

Certificats clients

ClientCertificateMode configure les exigences du certificat client.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "ClientCertificateMode": "AllowCertificate",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, le mot de passe du certificat est stocké en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe du certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault.

La valeur par défaut est ClientCertificateMode.NoCertificate, tandis que Kestrel ne demande ni n’exige un certificat de la part du client.

Pour plus d’informations, consultez Configurer l’authentification par certificat dans ASP.NET Core.

Journalisation des connexions

Appelez UseConnectionLogging pour émettre des journaux de niveau débogage pour les communications au niveau des octets sur une connexion. La journalisation des connexions est utile pour résoudre les problèmes de communication de bas niveau, tels que pendant le chiffrement TLS et derrière les proxys. Si UseConnectionLogging est placé avant UseHttps, le trafic chiffré est journalisé. Si UseConnectionLogging est placé après UseHttps, le trafic déchiffré est journalisé. Il s’agit d’un Intergiciel de connexion intégré.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseConnectionLogging();
    });
});

Lier à un socket TCP

La méthode Listen se lie à un socket TCP, et une expression lambda options permet la configuration d’un certificat X.509 :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

L’exemple configure HTTPS pour un point de terminaison avec ListenOptions. Utilisez la même API afin de configurer d’autres paramètres Kestrel pour des points de terminaison spécifiques.

Pour créer des certificats auto-signés sous Windows, vous pouvez utiliser l’applet de commande PowerShell New-SelfSignedCertificate. Pour obtenir un exemple non pris en charge, consultez UpdateIISExpressSSLForChrome.ps1.

OpenSSL permet de créer des certificats sous macOS, Linux et Windows.

Lier à un socket Unix

Écoutez sur un socket Unix avec ListenUnixSocket pour améliorer les performances avec Nginx, comme illustré dans cet exemple :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
  • Dans le fichier de configuration Nginx, définissez l’entrée server>location>proxy_pass sur http://unix:/tmp/{KESTREL SOCKET}:/;. {KESTREL SOCKET} est le nom du socket fourni à ListenUnixSocket (par exemple, kestrel-test.sock dans l’exemple précédent).
  • Vérifiez que le socket est accessible en écriture par Nginx (par exemple, chmod go+w /tmp/kestrel-test.sock).

Port 0

Si vous spécifiez le numéro de port 0, Kestrel se lie dynamiquement à un port disponible. L’exemple suivant montre comment déterminer le port auquel Kestrel se lie au moment de l’exécution :

app.Run(async (context) =>
{
    var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();

    if (serverAddressFeature is not null)
    {
        var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);

        // ...
    }
});

La liaison dynamique d’un port n’est pas disponible dans certaines situations :

  • ListenLocalhost
  • Liaison entre HTTP/1.1 ou HTTP/2, basés sur TCP, et HTTP/3, basés sur QUIC.

Limitations

Configurez des points de terminaison avec les approches suivantes :

  • UseUrls
  • Arguments de ligne de commande --urls
  • La clé de configuration d’hôte urls
  • ASPNETCORE_URLS variable d’environnement

Ces méthodes sont utiles si vous voulez que votre code fonctionne avec des serveurs autres que Kestrel. Toutefois, soyez conscient des limitations suivantes :

  • HTTPS ne peut pas être utilisé avec ces approches, sauf si un certificat par défaut est fourni dans la configuration du point de terminaison HTTPS (par exemple avec la configuration KestrelServerOptions ou un fichier de configuration, comme illustré plus haut dans cet article).
  • Quand les deux approches Listen et UseUrls sont utilisées simultanément, les points de terminaison Listen remplacent les points de terminaison UseUrls.

Configuration de point de terminaison IIS

Quand vous utilisez IIS, les liaisons d’URL pour IIS remplacent les liaisons qui sont définies par Listen ou par UseUrls. Pour plus d’informations, consultez Module ASP.NET Core.

ListenOptions.Protocols

La propriété Protocols établit les protocoles HTTP (HttpProtocols) activés sur un point de terminaison de connexion ou pour le serveur. Affectez une valeur à la propriété Protocols à partir de l’énumération HttpProtocols.

Valeur enum HttpProtocols Protocole de connexion autorisé
Http1 HTTP/1.1 uniquement. Peut être utilisé avec ou sans TLS.
Http2 HTTP/2 uniquement. Peut être utilisé sans TLS, uniquement si le client prend en charge un mode de connaissance préalable (Prior Knowledge).
Http3 HTTP/3 uniquement. Nécessite TLS. Le client doit peut-être être configuré pour utiliser HTTP/3 uniquement.
Http1AndHttp2 HTTP/1.1 et HTTP/2. HTTP/2 nécessite que le client sélectionne HTTP/2 dans l’établissement d’une liaison TLS ALPN (Application-Layer Protocol Negotiation) ; sinon, la connexion est établie par défaut sur HTTP/1.1.
Http1AndHttp2AndHttp3 HTTP/1.1, HTTP/2 et HTTP/3. La première requête client utilise normalement HTTP/1.1 ou HTTP/2, et l’en-tête de alt-svc réponse invite le client à effectuer une mise à niveau vers HTTP/3. HTTP/2 et HTTP/3 nécessitent TLS ; sinon, la connexion par défaut est HTTP/1.1.

La valeur ListenOptions.Protocols par défaut pour n’importe quel point de terminaison est HttpProtocols.Http1AndHttp2.

Restrictions TLS pour HTTP/2 :

  • TLS version 1.2 ou ultérieure
  • Renégociation désactivée
  • Compression désactivée
  • Tailles minimales de l’échange de clé éphémère :
    • Diffie-Hellman à courbe elliptique (ECDHE) [RFC4492] : 224 bits minimum
    • Diffie-Hellman à champ fini (DHE) [TLS12] : 2048 bits minimum
  • Suite de chiffrement non interdite.

Prise en charge par défaut de TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] avec la courbe elliptique P-256 [FIPS186].

L’exemple suivant autorise les connexions HTTP/1.1 et HTTP/2 sur le port 8000. Les connexions sont sécurisées par TLS avec un certificat fourni :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
    });
});

Sur Linux, CipherSuitesPolicy peut être utilisé pour filtrer les établissements de liaisons TLS par connexion :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.OnAuthenticate = (context, sslOptions) =>
        {
            sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
                new[]
                {
                    TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                    TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
                    // ...
                });
        };
    });
});

Intergiciel de connexion

L’intergiciel de connexion personnalisé peut filtrer l’établissement de liaisons TLS par connexion pour des chiffrements spécifiques si nécessaire.

L’exemple suivant renvoie NotSupportedException pour tout algorithme de chiffrement que l’application ne prend pas en charge. Vous pouvez également définir et comparer ITlsHandshakeFeature.CipherAlgorithm à une liste de suites de chiffrement acceptables.

Aucun chiffrement n'est utilisé avec un algorithme de chiffrement CipherAlgorithmType.Null.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");

        listenOptions.Use((context, next) =>
        {
            var tlsFeature = context.Features.Get<ITlsHandshakeFeature>()!;

            if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
            {
                throw new NotSupportedException(
                    $"Prohibited cipher: {tlsFeature.CipherAlgorithm}");
            }

            return next();
        });
    });
});

Définissez le protocole HTTP à partir de la configuration

Par défaut, la configuration Kestrel est chargée à partir de la section Kestrel. L’exemple appsettings.json suivant établit HTTP/1.1 comme protocole de connexion par défaut pour tous les points de terminaison :

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1"
    }
  }
}

L’exemple appsettings.json suivant établit le protocole de connexion HTTP/1.1 pour un point de terminaison spécifique :

{
  "Kestrel": {
    "Endpoints": {
      "HttpsDefaultCert": {
        "Url": "https://localhost:5001",
        "Protocols": "Http1"
      }
    }
  }
}

Les protocoles spécifiés dans le code remplacent les valeurs définies par configuration.

Préfixes d’URL

Quand vous utilisez UseUrls, l’argument de ligne de commande --urls, la clé de configuration d’hôte urls ou la variable d’environnement ASPNETCORE_URLS, les préfixes d’URL peuvent être dans un des formats suivants.

Seuls les préfixes d’URL HTTP sont valides. Kestrel ne prend pas en charge HTTPS lors de la configuration de liaisons d’URL à l’aide de UseUrls.

  • Adresse IPv4 avec numéro de port

    http://65.55.39.10:80/
    

    0.0.0.0 est un cas spécial qui se lie à toutes les adresses IPv4.

  • Adresse IPv6 avec numéro de port

    http://[0:0:0:0:0:ffff:4137:270a]:80/
    

    [::] est l’équivalent IPv6 de 0.0.0.0 dans IPv4.

  • Nom d’hôte avec numéro de port

    http://contoso.com:80/
    http://*:80/
    

    Les noms d’hôte, * et + ne sont pas spéciaux. Tout ce qui n’est pas reconnu comme adresse IP valide ou localhost se lie à toutes les adresses IP IPv4 et IPv6. Pour lier différents noms d’hôte à différentes applications ASP.NET Core sur le même port, utilisez HTTP.sys ou un serveur proxy inverse. Les exemples de serveur proxy inverse incluent IIS, Nginx ou Apache.

    Avertissement

    L’hébergement dans une configuration de proxy inverse nécessite le filtrage d’hôte.

  • Nom localhost de l’hôte avec numéro de port ou adresse IP de bouclage avec numéro de port

    http://localhost:5000/
    http://127.0.0.1:5000/
    http://[::1]:5000/
    

    Quand localhost est spécifié, Kestrel tente de se lier aux interfaces de bouclage IPv4 et IPv6. Si le port requis est en cours d’utilisation par un autre service sur l’une des interfaces de bouclage, Kestrel ne démarre pas. Si l’une des interfaces de bouclage n’est pas disponible pour une raison quelconque (généralement du fait de la non-prise en charge d’IPv6), Kestrel journalise un avertissement.

Les projets ASP.NET Core sont configurés pour être liés à un port HTTP aléatoire compris entre 5 000 et 5 300 et à un port HTTPS aléatoire compris entre 7 000 et 7 300. Cette configuration par défaut est spécifiée dans le fichier Properties/launchSettings.json généré et peut être remplacée. Si aucun port n’est spécifié, Kestrel est lié à :

  • http://localhost:5000
  • https://localhost:5001 (quand un certificat de développement local est présent)

Spécifiez les URL avec :

  • La variable d’environnement ASPNETCORE_URLS.
  • L’argument de ligne de commande --urls.
  • La clé de configuration d’hôte urls.
  • La méthode d’extension UseUrls.

La valeur fournie avec ces approches peut être un ou plusieurs points de terminaison HTTP et HTTPS (HTTPS si un certificat par défaut est disponible). Configurez la valeur sous forme de liste délimitée par des points-virgules (par exemple "Urls": "http://localhost:8000;http://localhost:8001").

Pour plus d’informations sur ces approches, voir URL de serveur et Remplacer la configuration.

Un certificat de développement est créé :

Le certificat de développement est disponible uniquement pour l’utilisateur qui génère le certificat. Certains navigateurs nécessitent l’autorisation explicite pour faire confiance au certificat de développement local.

Les modèles de projet configurent les applications pour qu’elles s’exécutent sur HTTPS par défaut et incluent la redirection HTTPS et la prise en charge HSTS.

Appelez les méthodes Listen ou ListenUnixSocket sur KestrelServerOptions pour configurer les préfixes et les ports d’URL pour Kestrel.

UseUrls, l’argument de ligne de commande --urls, la clé de configuration d’hôte urls et la variable d’environnement ASPNETCORE_URLS fonctionnent également, mais ils présentent les limitations indiquées plus loin dans cette section (un certificat par défaut doit être disponible pour la configuration du point de terminaison HTTPS).

ConfigurationKestrelServerOptions :

ConfigureEndpointDefaults

ConfigureEndpointDefaults(Action<ListenOptions>) spécifie une configuration Action à exécuter pour chaque point de terminaison spécifié. Le fait d’appeler ConfigureEndpointDefaults plusieurs fois remplace les Action précédents par le dernier Action spécifié :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });
});

Note

Les points de terminaison créés en appelant Listen avant d’appeler ConfigureEndpointDefaults n’ont pas les valeurs par défaut appliquées.

Configure(IConfiguration)

Permet à Kestrel de charger des points de terminaison à partir d’un IConfiguration. La configuration doit être étendue à la section de configuration pour Kestrel. La surcharge Configure(IConfiguration, bool) peut être utilisée pour activer le rechargement des points de terminaison lorsque la source de configuration change.

Par défaut, la configuration Kestrel est chargée à partir de la section Kestrel et le rechargement des modifications est activé :

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "Https": {
        "Url": "https://localhost:5001"
      }
    }
  }
}

Si la configuration de rechargement est activée et qu’une modification est signalée, les étapes suivantes sont suivies :

  • La nouvelle configuration est comparée à l’ancienne. Aucun point de terminaison sans modification de configuration n’est modifié.
  • Les points de terminaison supprimés ou modifiés ont 5 secondes pour terminer le traitement des requêtes et s’arrêter.
  • Les points de terminaison nouveaux ou modifiés sont démarrés.

Les clients qui se connectent à un point de terminaison modifié peuvent être déconnectés ou refusés pendant le redémarrage du point de terminaison.

ConfigureHttpsDefaults

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) spécifie une configuration Action à exécuter pour chaque point de terminaison HTTPS. Le fait d’appeler ConfigureHttpsDefaults plusieurs fois remplace les Actions précédentes par la dernière Action spécifiée.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

Note

Les points de terminaison créés en appelant Listen avant d’appeler ConfigureHttpsDefaults n’ont pas les valeurs par défaut appliquées.

ListenOptions.UseHttps

Configurez Kestrel pour utiliser HTTPS.

Extensions de ListenOptions.UseHttps :

  • UseHttps : configurez Kestrel pour utiliser HTTPS avec le certificat par défaut. Lève une exception si aucun certificat par défaut n’est configuré.
  • UseHttps(string fileName)
  • UseHttps(string fileName, string password)
  • UseHttps(string fileName, string password, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(StoreName storeName, string subject)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(X509Certificate2 serverCertificate)
  • UseHttps(X509Certificate2 serverCertificate, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(Action<HttpsConnectionAdapterOptions> configureOptions)

Paramètres de ListenOptions.UseHttps :

  • filename est le chemin et le nom d’un fichier de certificat, relatif au répertoire qui contient les fichiers de contenu de l’application.
  • password est le mot de passe nécessaire pour accéder aux données du certificat X.509.
  • configureOptions est une Action pour configurer les HttpsConnectionAdapterOptions. Retourne l'ListenOptions.
  • storeName est le magasin de certificats à partir duquel charger le certificat.
  • subject est le nom du sujet du certificat.
  • allowInvalid indique si les certificats non valides doivent être considérés, comme les certificats auto-signés.
  • location est l’emplacement du magasin à partir duquel charger le certificat.
  • serverCertificate est le certificat X.509.

En production, HTTPS doit être explicitement configuré. Au minimum, un certificat par défaut doit être fourni.

Configurations prises en charge décrites dans la suite :

  • Pas de configuration
  • Remplacer le certificat par défaut dans la configuration
  • Changer les valeurs par défaut dans le code

Pas de configuration

Kestrel écoute sur http://localhost:5000 et sur https://localhost:5001 (si un certificat par défaut est disponible).

Remplacer le certificat par défaut dans la configuration

Un schéma de configuration des paramètres d’application HTTPS par défaut est disponible pour Kestrel. Configurez plusieurs points de terminaison, notamment les URL et les certificats à utiliser, à partir d’un fichier sur disque ou d’un magasin de certificats.

Dans l’exemple appsettings.json suivant :

  • Définissez AllowInvalid sur true pour permettre l’utilisation de certificats non valides (par exemple des certificats auto-signés).
  • Tout point de terminaison HTTPS qui ne spécifie pas de certificat (HttpsDefaultCert dans l’exemple qui suit) revient au certificat défini sous Certificates:Default ou au certificat de développement.
{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, les mots de passe de certificat sont stockés en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe de chaque certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

Notes de schéma :

  • Les noms des points de terminaison ne respectent pas la casse. Par exemple, HTTPS and Https sont équivalentes.
  • Le paramètre Url est obligatoire pour chaque point de terminaison. Le format de ce paramètre est le même que celui du paramètre de configuration Urls du plus haut niveau, sauf qu’il est limité à une seule valeur.
  • Ces points de terminaison remplacent ceux qui sont définis dans le paramètre de configuration Urls du plus haut niveau configuration, au lieu de s’y ajouter. Les points de terminaison définis dans le code via Listen sont cumulatifs avec les points de terminaison définis dans la section de configuration.
  • La section Certificate est facultative. Si la section Certificate n’est pas spécifiée, les valeurs par défaut définies dans Certificates:Default sont utilisées. Si aucune valeur par défaut n’est disponible, le certificat de développement est utilisé. S’il n’existe aucune valeur par défaut et que le certificat de développement n’est pas présent, le serveur lève une exception et ne parvient pas à démarrer.
  • La section Certificate prend en charge plusieurs sources de certificats.
  • Vous pouvez définir un nombre quelconque de points de terminaison Configuration, pour autant qu’ils ne provoquent pas de conflits de port.

Sources de certificat

Les nœuds de certificat peuvent être configurés pour charger des certificats à partir d’un certain nombre de sources :

  • Path et Password pour charger des fichiers .pfx.
  • Path, KeyPath et Password pour charger des fichiers .pem/.crt et .key.
  • Subject et Store pour charger à partir du magasin de certificats.

Par exemple, le certificat Certificates:Default peut être spécifié comme suit :

"Default": {
  "Subject": "<subject; required>",
  "Store": "<cert store; required>",
  "Location": "<location; defaults to CurrentUser>",
  "AllowInvalid": "<true or false; defaults to false>"
}

ChargeurDeConfiguration

Configure(IConfiguration) retourne un KestrelConfigurationLoader avec une méthode Endpoint(String, Action<EndpointConfiguration>) qui peut être utilisée pour compléter les paramètres d’un point de terminaison configuré :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    var kestrelSection = context.Configuration.GetSection("Kestrel");

    serverOptions.Configure(kestrelSection)
        .Endpoint("HTTPS", listenOptions =>
        {
            // ...
        });
});

Vous pouvez accéder directement à KestrelServerOptions.ConfigurationLoader pour continuer l’itération sur le chargeur existant, comme celui fourni par WebApplicationBuilder.WebHost.

  • La section de configuration pour chaque point de terminaison est disponible sur les options de la méthode Endpoint, ce qui permet de lire les paramètres personnalisés.
  • Plusieurs configurations peuvent être chargées en rappelant Configure(IConfiguration) avec une autre section. Seule la dernière configuration est utilisée, à moins que Load soit explicitement appelé sur les instances précédentes. Le métapackage n’appelle pas Load : sa section de configuration par défaut peut donc être remplacée.
  • KestrelConfigurationLoader reflète la famille d’API Listen de KestrelServerOptions sous forme de surcharges de Endpoint : le code et les points de terminaison de configuration peuvent donc être configurés au même emplacement. Ces surcharges n’utilisent pas de noms et consomment seulement les paramètres par défaut de la configuration.

Changer les valeurs par défaut dans le code

ConfigureEndpointDefaults et ConfigureHttpsDefaults peuvent être utilisés pour modifier les paramètres par défaut pour ListenOptions et HttpsConnectionAdapterOptions, notamment en remplaçant le certificat par défaut spécifié dans le scénario précédent. ConfigureEndpointDefaults et ConfigureHttpsDefaults doivent être appelés avant que des points de terminaison soient configurés.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });

    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

Configurez des points de terminaison à l’aide de l’Indication du nom du serveur

L’indication du nom de serveur (SNI, Server Name Indication) peut être utilisée pour héberger plusieurs domaines sur la même adresse IP et le même port. Pour que SNI fonctionne, le client envoie le nom d’hôte pour la session sécurisée au serveur pendant la négociation TLS afin que le serveur puisse fournir le certificat correct. Le client utilise le certificat fourni pour la communication chiffrée avec le serveur pendant la session sécurisée qui suit la négociation TLS.

L’Indication du nom du serveur peut être configurée de deux manières :

  • Créez un point de terminaison dans le code et sélectionnez un certificat en utilisant le nom d’hôte avec le rappel ServerCertificateSelector.
  • Configurez un mappage entre les noms d’hôtes et les options HTTPS dans Configuration. Par exemple, JSON dans le fichier appsettings.json.

SNI avec ServerCertificateSelector

Kestrel prend en charge l’indication du nom du serveur via le rappel ServerCertificateSelector. Le rappel est appelé une fois par connexion pour permettre à l’application d’inspecter le nom d’hôte et de sélectionner le certificat approprié :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var subExampleCert = CertificateLoader.LoadFromStoreCert(
                "sub.example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var certs = new Dictionary<string, X509Certificate2>(
                StringComparer.OrdinalIgnoreCase)
            {
                ["localhost"] = localhostCert,
                ["example.com"] = exampleCert,
                ["sub.example.com"] = subExampleCert
            };

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name is not null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

SNI avec ServerOptionsSelectionCallback

Kestrel prend en charge une configuration TLS dynamique supplémentaire via le rappel ServerOptionsSelectionCallback. Le rappel est appelé une fois par connexion pour permettre à l’application d’inspecter le nom d’hôte et de sélectionner le certificat et la configuration TLS appropriés. Les certificats par défaut et ConfigureHttpsDefaults ne sont pas utilisés avec ce rappel.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);

            listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
            {
                if (string.Equals(clientHelloInfo.ServerName, "localhost",
                    StringComparison.OrdinalIgnoreCase))
                {
                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = localhostCert,
                            // Different TLS requirements for this host
                            ClientCertificateRequired = true
                        });
                }

                return new ValueTask<SslServerAuthenticationOptions>(
                    new SslServerAuthenticationOptions
                    {
                        ServerCertificate = exampleCert
                    });
            }, state: null!);
        });
    });
});

SNI avec TlsHandshakeCallbackOptions

Kestrel prend en charge une configuration TLS dynamique supplémentaire via le rappel TlsHandshakeCallbackOptions.OnConnection. Le rappel est appelé une fois par connexion pour permettre à l’application d’inspecter le nom d’hôte et de sélectionner le certificat, la configuration TLS et d’autres options de serveur appropriés. Les certificats par défaut et ConfigureHttpsDefaults ne sont pas utilisés avec ce rappel.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);

            listenOptions.UseHttps(new TlsHandshakeCallbackOptions
            {
                OnConnection = context =>
                {
                    if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
                        StringComparison.OrdinalIgnoreCase))
                    {
                        // Different TLS requirements for this host
                        context.AllowDelayedClientCertificateNegotation = true;

                        return new ValueTask<SslServerAuthenticationOptions>(
                            new SslServerAuthenticationOptions
                            {
                                ServerCertificate = localhostCert
                            });
                    }

                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = exampleCert
                        });
                }
            });
        });
    });
});

SNI dans la configuration

Kestrel prend en charge l’indication du nom du serveur définie dans la configuration. Un point de terminaison peut être configuré avec un objet Sni qui contient un mappage entre les noms d’hôtes et les options HTTPS. Le nom d’hôte de la connexion est associé aux options et elles sont utilisées pour cette connexion.

La configuration suivante ajoute un point de terminaison nommé MySniEndpoint qui utilise l’indication du nom du serveur pour sélectionner les options HTTPS en fonction du nom d’hôte :

{
  "Kestrel": {
    "Endpoints": {
      "MySniEndpoint": {
        "Url": "https://*",
        "SslProtocols": ["Tls11", "Tls12"],
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": ["Tls11", "Tls12", "Tls13"],
            "Certificate": {
              "Subject": "<subject; required>",
              "Store": "<certificate store; required>",
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "<path to .pfx file>",
              "Password": "$CREDENTIAL_PLACEHOLDER$"
            }
          },
          "*": {
            // At least one subproperty needs to exist per SNI section or it
            // cannot be discovered via IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, les mots de passe de certificat sont stockés en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe de chaque certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

Options HTTPS qui peuvent être remplacées par l’indication du nom du serveur :

Le nom d’hôte prend en charge la correspondance de caractères génériques :

  • Correspondance exacte. Par exemples, a.example.org correspond à a.example.org.
  • Préfixe de caractère générique. S’il existe plusieurs correspondances de caractère générique, le modèle le plus long est choisi. Par exemple, *.example.org correspond à b.example.org et c.example.org.
  • Caractère générique complet. * correspond à tout le reste, y compris les clients qui n’utilisent pas l’indication du nom du serveur et n’envoient pas de nom d’hôte.

La configuration de l’indication du nom du serveur correspondante est appliquée au point de terminaison de la connexion, en remplaçant les valeurs sur le point de terminaison. Si une connexion ne correspond pas à un nom d’hôte de l’indication du nom du serveur configuré, la connexion est refusée.

Conditions requises pour l’indication du nom du serveur

Tous les sites web doivent s’exécuter sur la même instance Kestrel. Kestrel ne prend pas en charge le partage d’une adresse IP et d’un port entre plusieurs instances sans un proxy inverse.

Protocoles SSL/TLS

Les protocoles SSL sont des protocoles utilisés pour chiffrer et déchiffrer le trafic entre deux homologues, généralement un client et un serveur.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls13;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "SslProtocols": ["Tls12", "Tls13"],
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, le mot de passe du certificat est stocké en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe du certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

La valeur par défaut, SslProtocols.None, fait en sorte que Kestrel utilise les valeurs par défaut du système d’exploitation pour choisir le meilleur protocole. Sauf si vous avez une raison particulière de sélectionner un protocole, utilisez la valeur par défaut.

Certificats clients

ClientCertificateMode configure les exigences du certificat client.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "ClientCertificateMode": "AllowCertificate",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, le mot de passe du certificat est stocké en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe du certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault.

La valeur par défaut est ClientCertificateMode.NoCertificate, tandis que Kestrel ne demande ni n’exige un certificat de la part du client.

Pour plus d’informations, consultez Configurer l’authentification par certificat dans ASP.NET Core.

Journalisation des connexions

Appelez UseConnectionLogging pour émettre des journaux de niveau débogage pour les communications au niveau des octets sur une connexion. La journalisation des connexions est utile pour résoudre les problèmes de communication de bas niveau, tels que pendant le chiffrement TLS et derrière les proxys. Si UseConnectionLogging est placé avant UseHttps, le trafic chiffré est journalisé. Si UseConnectionLogging est placé après UseHttps, le trafic déchiffré est journalisé. Il s’agit d’un Intergiciel de connexion intégré.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseConnectionLogging();
    });
});

Lier à un socket TCP

La méthode Listen se lie à un socket TCP, et une expression lambda options permet la configuration d’un certificat X.509 :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

L’exemple configure HTTPS pour un point de terminaison avec ListenOptions. Utilisez la même API afin de configurer d’autres paramètres Kestrel pour des points de terminaison spécifiques.

Pour créer des certificats auto-signés sous Windows, vous pouvez utiliser l’applet de commande PowerShell New-SelfSignedCertificate. Pour obtenir un exemple non pris en charge, consultez UpdateIISExpressSSLForChrome.ps1.

OpenSSL permet de créer des certificats sous macOS, Linux et Windows.

Lier à un socket Unix

Écoutez sur un socket Unix avec ListenUnixSocket pour améliorer les performances avec Nginx, comme illustré dans cet exemple :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
  • Dans le fichier de configuration Nginx, définissez l’entrée server>location>proxy_pass sur http://unix:/tmp/{KESTREL SOCKET}:/;. {KESTREL SOCKET} est le nom du socket fourni à ListenUnixSocket (par exemple, kestrel-test.sock dans l’exemple précédent).
  • Vérifiez que le socket est accessible en écriture par Nginx (par exemple, chmod go+w /tmp/kestrel-test.sock).

Port 0

Si vous spécifiez le numéro de port 0, Kestrel se lie dynamiquement à un port disponible. L’exemple suivant montre comment déterminer le port auquel Kestrel se lie au moment de l’exécution :

app.Run(async (context) =>
{
    var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();

    if (serverAddressFeature is not null)
    {
        var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);

        // ...
    }
});

Limitations

Configurez des points de terminaison avec les approches suivantes :

  • UseUrls
  • Arguments de ligne de commande --urls
  • La clé de configuration d’hôte urls
  • ASPNETCORE_URLS variable d’environnement

Ces méthodes sont utiles si vous voulez que votre code fonctionne avec des serveurs autres que Kestrel. Toutefois, soyez conscient des limitations suivantes :

  • HTTPS ne peut pas être utilisé avec ces approches, sauf si un certificat par défaut est fourni dans la configuration du point de terminaison HTTPS (par exemple avec la configuration KestrelServerOptions ou un fichier de configuration, comme illustré plus haut dans cet article).
  • Quand les deux approches Listen et UseUrls sont utilisées simultanément, les points de terminaison Listen remplacent les points de terminaison UseUrls.

Configuration de point de terminaison IIS

Quand vous utilisez IIS, les liaisons d’URL pour IIS remplacent les liaisons qui sont définies par Listen ou par UseUrls. Pour plus d’informations, consultez Module ASP.NET Core.

ListenOptions.Protocols

La propriété Protocols établit les protocoles HTTP (HttpProtocols) activés sur un point de terminaison de connexion ou pour le serveur. Affectez une valeur à la propriété Protocols à partir de l’énumération HttpProtocols.

Valeur enum HttpProtocols Protocole de connexion autorisé
Http1 HTTP/1.1 uniquement. Peut être utilisé avec ou sans TLS.
Http2 HTTP/2 uniquement. Peut être utilisé sans TLS, uniquement si le client prend en charge un mode de connaissance préalable (Prior Knowledge).
Http1AndHttp2 HTTP/1.1 et HTTP/2. HTTP/2 nécessite que le client sélectionne HTTP/2 dans l’établissement d’une liaison TLS ALPN (Application-Layer Protocol Negotiation) ; sinon, la connexion est établie par défaut sur HTTP/1.1.

La valeur ListenOptions.Protocols par défaut pour n’importe quel point de terminaison est HttpProtocols.Http1AndHttp2.

Restrictions TLS pour HTTP/2 :

  • TLS version 1.2 ou ultérieure
  • Renégociation désactivée
  • Compression désactivée
  • Tailles minimales de l’échange de clé éphémère :
    • Diffie-Hellman à courbe elliptique (ECDHE) [RFC4492] : 224 bits minimum
    • Diffie-Hellman à champ fini (DHE) [TLS12] : 2048 bits minimum
  • Suite de chiffrement non interdite.

Prise en charge par défaut de TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] avec la courbe elliptique P-256 [FIPS186].

L’exemple suivant autorise les connexions HTTP/1.1 et HTTP/2 sur le port 8000. Les connexions sont sécurisées par TLS avec un certificat fourni :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
    });
});

Sur Linux, CipherSuitesPolicy peut être utilisé pour filtrer les établissements de liaisons TLS par connexion :

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.OnAuthenticate = (context, sslOptions) =>
        {
            sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
                new[]
                {
                    TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                    TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
                    // ...
                });
        };
    });
});

Intergiciel de connexion

L’intergiciel de connexion personnalisé peut filtrer l’établissement de liaisons TLS par connexion pour des chiffrements spécifiques si nécessaire.

L’exemple suivant renvoie NotSupportedException pour tout algorithme de chiffrement que l’application ne prend pas en charge. Vous pouvez également définir et comparer ITlsHandshakeFeature.CipherAlgorithm à une liste de suites de chiffrement acceptables.

Aucun chiffrement n'est utilisé avec un algorithme de chiffrement CipherAlgorithmType.Null.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");

        listenOptions.Use((context, next) =>
        {
            var tlsFeature = context.Features.Get<ITlsHandshakeFeature>()!;

            if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
            {
                throw new NotSupportedException(
                    $"Prohibited cipher: {tlsFeature.CipherAlgorithm}");
            }

            return next();
        });
    });
});

Définissez le protocole HTTP à partir de la configuration

Par défaut, la configuration Kestrel est chargée à partir de la section Kestrel. L’exemple appsettings.json suivant établit HTTP/1.1 comme protocole de connexion par défaut pour tous les points de terminaison :

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1"
    }
  }
}

L’exemple appsettings.json suivant établit le protocole de connexion HTTP/1.1 pour un point de terminaison spécifique :

{
  "Kestrel": {
    "Endpoints": {
      "HttpsDefaultCert": {
        "Url": "https://localhost:5001",
        "Protocols": "Http1"
      }
    }
  }
}

Les protocoles spécifiés dans le code remplacent les valeurs définies par configuration.

Préfixes d’URL

Quand vous utilisez UseUrls, l’argument de ligne de commande --urls, la clé de configuration d’hôte urls ou la variable d’environnement ASPNETCORE_URLS, les préfixes d’URL peuvent être dans un des formats suivants.

Seuls les préfixes d’URL HTTP sont valides. Kestrel ne prend pas en charge HTTPS lors de la configuration de liaisons d’URL à l’aide de UseUrls.

  • Adresse IPv4 avec numéro de port

    http://65.55.39.10:80/
    

    0.0.0.0 est un cas spécial qui se lie à toutes les adresses IPv4.

  • Adresse IPv6 avec numéro de port

    http://[0:0:0:0:0:ffff:4137:270a]:80/
    

    [::] est l’équivalent IPv6 de 0.0.0.0 dans IPv4.

  • Nom d’hôte avec numéro de port

    http://contoso.com:80/
    http://*:80/
    

    Les noms d’hôte, * et + ne sont pas spéciaux. Tout ce qui n’est pas reconnu comme adresse IP valide ou localhost se lie à toutes les adresses IP IPv4 et IPv6. Pour lier différents noms d’hôte à différentes applications ASP.NET Core sur le même port, utilisez HTTP.sys ou un serveur proxy inverse. Les exemples de serveur proxy inverse incluent IIS, Nginx ou Apache.

    Avertissement

    L’hébergement dans une configuration de proxy inverse nécessite le filtrage d’hôte.

  • Nom localhost de l’hôte avec numéro de port ou adresse IP de bouclage avec numéro de port

    http://localhost:5000/
    http://127.0.0.1:5000/
    http://[::1]:5000/
    

    Quand localhost est spécifié, Kestrel tente de se lier aux interfaces de bouclage IPv4 et IPv6. Si le port requis est en cours d’utilisation par un autre service sur l’une des interfaces de bouclage, Kestrel ne démarre pas. Si l’une des interfaces de bouclage n’est pas disponible pour une raison quelconque (généralement du fait de la non-prise en charge d’IPv6), Kestrel journalise un avertissement.

Par défaut, ASP.NET Core se lie à :

  • http://localhost:5000
  • https://localhost:5001 (quand un certificat de développement local est présent)

Spécifiez les URL avec :

  • La variable d’environnement ASPNETCORE_URLS.
  • L’argument de ligne de commande --urls.
  • La clé de configuration d’hôte urls.
  • La méthode d’extension UseUrls.

La valeur fournie avec ces approches peut être un ou plusieurs points de terminaison HTTP et HTTPS (HTTPS si un certificat par défaut est disponible). Configurez la valeur sous forme de liste délimitée par des points-virgules (par exemple "Urls": "http://localhost:8000;http://localhost:8001").

Pour plus d’informations sur ces approches, voir URL de serveur et Remplacer la configuration.

Un certificat de développement est créé :

Certains navigateurs nécessitent l’autorisation explicite pour faire confiance au certificat de développement local.

Les modèles de projet configurent les applications pour qu’elles s’exécutent sur HTTPS par défaut et incluent la redirection HTTPS et la prise en charge HSTS.

Appelez les méthodes Listen ou ListenUnixSocket sur KestrelServerOptions pour configurer les préfixes et les ports d’URL pour Kestrel.

UseUrls, l’argument de ligne de commande --urls, la clé de configuration d’hôte urls et la variable d’environnement ASPNETCORE_URLS fonctionnent également, mais ils présentent les limitations indiquées plus loin dans cette section (un certificat par défaut doit être disponible pour la configuration du point de terminaison HTTPS).

ConfigurationKestrelServerOptions :

ConfigureEndpointDefaults

ConfigureEndpointDefaults(Action<ListenOptions>) spécifie une configuration Action à exécuter pour chaque point de terminaison spécifié. Le fait d’appeler ConfigureEndpointDefaults plusieurs fois remplace les Actions précédentes par la dernière Action spécifiée.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // Configure endpoint defaults
    });
});

Note

Les points de terminaison créés en appelant Listen avant d’appeler ConfigureEndpointDefaults n’ont pas les valeurs par défaut appliquées.

Configure(IConfiguration)

Permet à Kestrel de charger des points de terminaison à partir d’un IConfiguration. La configuration doit être étendue à la section de configuration pour Kestrel.

La surcharge Configure(IConfiguration, bool) peut être utilisée pour activer le rechargement des points de terminaison lorsque la source de configuration change.

IHostBuilder.ConfigureWebHostDefaults appelle Configure(context.Configuration.GetSection("Kestrel"), reloadOnChange: true) par défaut pour charger la configuration Kestrel et activer le rechargement.

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "Https": {
        "Url": "https://localhost:5001"
      }
    }
  }
}

Si la configuration de rechargement est activée et qu’une modification est signalée, les étapes suivantes sont suivies :

  • La nouvelle configuration est comparée à l’ancienne. Aucun point de terminaison sans modification de configuration n’est modifié.
  • Les points de terminaison supprimés ou modifiés ont 5 secondes pour terminer le traitement des requêtes et s’arrêter.
  • Les points de terminaison nouveaux ou modifiés sont démarrés.

Les clients qui se connectent à un point de terminaison modifié peuvent être déconnectés ou refusés pendant le redémarrage du point de terminaison.

ConfigureHttpsDefaults

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) spécifie une configuration Action à exécuter pour chaque point de terminaison HTTPS. Le fait d’appeler ConfigureHttpsDefaults plusieurs fois remplace les Actions précédentes par la dernière Action spécifiée.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // certificate is an X509Certificate2
        listenOptions.ServerCertificate = certificate;
    });
});

Note

Les points de terminaison créés en appelant Listen avant d’appeler ConfigureHttpsDefaults n’ont pas les valeurs par défaut appliquées.

ListenOptions.UseHttps

Configurez Kestrel pour utiliser HTTPS.

Extensions de ListenOptions.UseHttps :

  • UseHttps : configurez Kestrel pour utiliser HTTPS avec le certificat par défaut. Lève une exception si aucun certificat par défaut n’est configuré.
  • UseHttps(string fileName)
  • UseHttps(string fileName, string password)
  • UseHttps(string fileName, string password, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(StoreName storeName, string subject)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(X509Certificate2 serverCertificate)
  • UseHttps(X509Certificate2 serverCertificate, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(Action<HttpsConnectionAdapterOptions> configureOptions)

Paramètres de ListenOptions.UseHttps :

  • filename est le chemin et le nom d’un fichier de certificat, relatif au répertoire qui contient les fichiers de contenu de l’application.
  • password est le mot de passe nécessaire pour accéder aux données du certificat X.509.
  • configureOptions est une Action pour configurer les HttpsConnectionAdapterOptions. Retourne l'ListenOptions.
  • storeName est le magasin de certificats à partir duquel charger le certificat.
  • subject est le nom du sujet du certificat.
  • allowInvalid indique si les certificats non valides doivent être considérés, comme les certificats auto-signés.
  • location est l’emplacement du magasin à partir duquel charger le certificat.
  • serverCertificate est le certificat X.509.

En production, HTTPS doit être explicitement configuré. Au minimum, un certificat par défaut doit être fourni.

Configurations prises en charge décrites dans la suite :

  • Pas de configuration
  • Remplacer le certificat par défaut dans la configuration
  • Changer les valeurs par défaut dans le code

Pas de configuration

Kestrel écoute sur http://localhost:5000 et sur https://localhost:5001 (si un certificat par défaut est disponible).

Remplacer le certificat par défaut dans la configuration

Un schéma de configuration des paramètres d’application HTTPS par défaut est disponible pour Kestrel. Configurez plusieurs points de terminaison, notamment les URL et les certificats à utiliser, à partir d’un fichier sur disque ou d’un magasin de certificats.

Dans l’exemple appsettings.json suivant :

  • Définissez AllowInvalid sur true pour permettre l’utilisation de certificats non valides (par exemple des certificats auto-signés).
  • Tout point de terminaison HTTPS qui ne spécifie pas de certificat (HttpsDefaultCert dans l’exemple qui suit) revient au certificat défini sous Certificates:Default ou au certificat de développement.
{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, les mots de passe de certificat sont stockés en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe de chaque certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

Notes de schéma :

  • Les noms des points de terminaison ne respectent pas la casse. Par exemple, HTTPS and Https sont équivalentes.
  • Le paramètre Url est obligatoire pour chaque point de terminaison. Le format de ce paramètre est le même que celui du paramètre de configuration Urls du plus haut niveau, sauf qu’il est limité à une seule valeur.
  • Ces points de terminaison remplacent ceux qui sont définis dans le paramètre de configuration Urls du plus haut niveau configuration, au lieu de s’y ajouter. Les points de terminaison définis dans le code via Listen sont cumulatifs avec les points de terminaison définis dans la section de configuration.
  • La section Certificate est facultative. Si la section Certificate n’est pas spécifiée, les valeurs par défaut définies dans Certificates:Default sont utilisées. Si aucune valeur par défaut n’est disponible, le certificat de développement est utilisé. S’il n’existe aucune valeur par défaut et que le certificat de développement n’est pas présent, le serveur lève une exception et ne parvient pas à démarrer.
  • La section Certificate prend en charge plusieurs sources de certificats.
  • Vous pouvez définir un nombre quelconque de points de terminaison Configuration, pour autant qu’ils ne provoquent pas de conflits de port.

Sources de certificat

Les nœuds de certificat peuvent être configurés pour charger des certificats à partir d’un certain nombre de sources :

  • Path et Password pour charger des fichiers .pfx.
  • Path, KeyPath et Password pour charger des fichiers .pem/.crt et .key.
  • Subject et Store pour charger à partir du magasin de certificats.

Par exemple, le certificat Certificates:Default peut être spécifié comme suit :

"Default": {
  "Subject": "<subject; required>",
  "Store": "<cert store; required>",
  "Location": "<location; defaults to CurrentUser>",
  "AllowInvalid": "<true or false; defaults to false>"
}

ChargeurDeConfiguration

options.Configure(context.Configuration.GetSection("{SECTION}")) retourne un KestrelConfigurationLoader avec une méthode .Endpoint(string name, listenOptions => { }) qui peut être utilisée pour compléter les paramètres d’un point de terminaison configuré :

webBuilder.UseKestrel((context, serverOptions) =>
{
    serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
        .Endpoint("HTTPS", listenOptions =>
        {
            listenOptions.HttpsOptions.SslProtocols = SslProtocols.Tls12;
        });
});

Vous pouvez accéder directement à KestrelServerOptions.ConfigurationLoader pour continuer l’itération sur le chargeur existant, comme celui fourni par CreateDefaultBuilder.

  • La section de configuration pour chaque point de terminaison est disponible sur les options de la méthode Endpoint, ce qui permet de lire les paramètres personnalisés.
  • Plusieurs configurations peuvent être chargées en rappelant options.Configure(context.Configuration.GetSection("{SECTION}")) avec une autre section. Seule la dernière configuration est utilisée, à moins que Load soit explicitement appelé sur les instances précédentes. Le métapackage n’appelle pas Load : sa section de configuration par défaut peut donc être remplacée.
  • KestrelConfigurationLoader reflète la famille d’API Listen de KestrelServerOptions sous forme de surcharges de Endpoint : le code et les points de terminaison de configuration peuvent donc être configurés au même emplacement. Ces surcharges n’utilisent pas de noms et consomment seulement les paramètres par défaut de la configuration.

Changer les valeurs par défaut dans le code

ConfigureEndpointDefaults et ConfigureHttpsDefaults peuvent être utilisés pour modifier les paramètres par défaut pour ListenOptions et HttpsConnectionAdapterOptions, notamment en remplaçant le certificat par défaut spécifié dans le scénario précédent. ConfigureEndpointDefaults et ConfigureHttpsDefaults doivent être appelés avant que des points de terminaison soient configurés.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // Configure endpoint defaults
    });

    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls12;
    });
});

Configurez des points de terminaison à l’aide de l’Indication du nom du serveur

L’indication du nom de serveur (SNI, Server Name Indication) peut être utilisée pour héberger plusieurs domaines sur la même adresse IP et le même port. Pour que SNI fonctionne, le client envoie le nom d’hôte pour la session sécurisée au serveur pendant la négociation TLS afin que le serveur puisse fournir le certificat correct. Le client utilise le certificat fourni pour la communication chiffrée avec le serveur pendant la session sécurisée qui suit la négociation TLS.

L’Indication du nom du serveur peut être configurée de deux manières :

  • Créez un point de terminaison dans le code et sélectionnez un certificat en utilisant le nom d’hôte avec le rappel ServerCertificateSelector.
  • Configurez un mappage entre les noms d’hôtes et les options HTTPS dans Configuration. Par exemple, JSON dans le fichier appsettings.json.

SNI avec ServerCertificateSelector

Kestrel prend en charge l’indication du nom du serveur via le rappel ServerCertificateSelector. Le rappel est appelé une fois par connexion pour permettre à l’application d’inspecter le nom d’hôte et de sélectionner le certificat approprié. Le code de rappel suivant peut être utilisé dans l’appel de méthode ConfigureWebHostDefaults du fichier Program.cs d’un projet :

// using System.Security.Cryptography.X509Certificates;
// using Microsoft.AspNetCore.Server.Kestrel.Https;

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var subExampleCert = CertificateLoader.LoadFromStoreCert(
                "sub.example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var certs = new Dictionary<string, X509Certificate2>(StringComparer.OrdinalIgnoreCase)
            {
                { "localhost", localhostCert },
                { "example.com", exampleCert },
                { "sub.example.com", subExampleCert },
            };            

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name != null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

SNI avec ServerOptionsSelectionCallback

Kestrel prend en charge une configuration TLS dynamique supplémentaire via le rappel ServerOptionsSelectionCallback. Le rappel est appelé une fois par connexion pour permettre à l’application d’inspecter le nom d’hôte et de sélectionner le certificat et la configuration TLS appropriés. Les certificats par défaut et ConfigureHttpsDefaults ne sont pas utilisés avec ce rappel.

// using System.Security.Cryptography.X509Certificates;
// using Microsoft.AspNetCore.Server.Kestrel.Https;

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);

            listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
            {
                if (string.Equals(clientHelloInfo.ServerName, "localhost", StringComparison.OrdinalIgnoreCase))
                {
                    return new ValueTask<SslServerAuthenticationOptions>(new SslServerAuthenticationOptions
                    {
                        ServerCertificate = localhostCert,
                        // Different TLS requirements for this host
                        ClientCertificateRequired = true,
                    });
                }

                return new ValueTask<SslServerAuthenticationOptions>(new SslServerAuthenticationOptions
                {
                    ServerCertificate = exampleCert,
                });
            }, state: null);
        });
    });
});

SNI dans la configuration

Kestrel prend en charge l’indication du nom du serveur définie dans la configuration. Un point de terminaison peut être configuré avec un objet Sni qui contient un mappage entre les noms d’hôtes et les options HTTPS. Le nom d’hôte de la connexion est associé aux options et elles sont utilisées pour cette connexion.

La configuration suivante ajoute un point de terminaison nommé MySniEndpoint qui utilise l’indication du nom du serveur pour sélectionner les options HTTPS en fonction du nom d’hôte :

{
  "Kestrel": {
    "Endpoints": {
      "MySniEndpoint": {
        "Url": "https://*",
        "SslProtocols": ["Tls11", "Tls12"],
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": ["Tls11", "Tls12", "Tls13"],
            "Certificate": {
              "Subject": "<subject; required>",
              "Store": "<certificate store; required>",
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "<path to .pfx file>",
              "Password": "$CREDENTIAL_PLACEHOLDER$"
            }
          },
          "*": {
            // At least one subproperty needs to exist per SNI section or it
            // cannot be discovered via IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, les mots de passe de certificat sont stockés en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe de chaque certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

Options HTTPS qui peuvent être remplacées par l’indication du nom du serveur :

Le nom d’hôte prend en charge la correspondance de caractères génériques :

  • Correspondance exacte. Par exemples, a.example.org correspond à a.example.org.
  • Préfixe de caractère générique. S’il existe plusieurs correspondances de caractère générique, le modèle le plus long est choisi. Par exemple, *.example.org correspond à b.example.org et c.example.org.
  • Caractère générique complet. * correspond à tout le reste, y compris les clients qui n’utilisent pas l’indication du nom du serveur et n’envoient pas de nom d’hôte.

La configuration de l’indication du nom du serveur correspondante est appliquée au point de terminaison de la connexion, en remplaçant les valeurs sur le point de terminaison. Si une connexion ne correspond pas à un nom d’hôte de l’indication du nom du serveur configuré, la connexion est refusée.

Conditions requises pour l’indication du nom du serveur

  • Exécution sur l’infrastructure cible netcoreapp2.1 ou version ultérieure. Sur net461 ou version ultérieure, le rappel est invoqué, mais le name est toujours null. name est également null si le client ne fournit pas le paramètre du nom d’hôte dans la négociation TLS.
  • Tous les sites web s’exécutent sur la même instance Kestrel. Kestrel ne prend pas en charge le partage d’une adresse IP et d’un port entre plusieurs instances sans un proxy inverse.

Protocoles SSL/TLS

Les protocoles SSL sont des protocoles utilisés pour chiffrer et déchiffrer le trafic entre deux homologues, généralement un client et un serveur.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls13;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "SslProtocols": ["Tls12", "Tls13"],
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, le mot de passe du certificat est stocké en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe du certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

La valeur par défaut, SslProtocols.None, fait en sorte que Kestrel utilise les valeurs par défaut du système d’exploitation pour choisir le meilleur protocole. Sauf si vous avez une raison particulière de sélectionner un protocole, utilisez la valeur par défaut.

Certificats clients

ClientCertificateMode configure les exigences du certificat client.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "ClientCertificateMode": "AllowCertificate",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avertissement

Dans l’exemple précédent, le mot de passe du certificat est stocké en texte brut dans appsettings.json. Le jeton $CREDENTIAL_PLACEHOLDER$ est utilisé comme espace réservé pour le mot de passe du certificat. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de développement, consultez Protéger les secrets dans le développement. Pour stocker les mots de passe de certificat en toute sécurité dans les environnements de production, consultez Fournisseur de configuration Azure Key Vault. Les secrets de développement ne doivent pas être utilisés pour la production ou le test.

La valeur par défaut est ClientCertificateMode.NoCertificate, tandis que Kestrel ne demande ni n’exige un certificat de la part du client.

Pour plus d’informations, consultez Configurer l’authentification par certificat dans ASP.NET Core.

Journalisation des connexions

Appelez UseConnectionLogging pour émettre des journaux de niveau débogage pour les communications au niveau des octets sur une connexion. La journalisation des connexions est utile pour résoudre les problèmes de communication de bas niveau, tels que pendant le chiffrement TLS et derrière les proxys. Si UseConnectionLogging est placé avant UseHttps, le trafic chiffré est journalisé. Si UseConnectionLogging est placé après UseHttps, le trafic déchiffré est journalisé. Il s’agit d’un Intergiciel de connexion intégré.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseConnectionLogging();
    });
});

Lier à un socket TCP

La méthode Listen se lie à un socket TCP, et une expression lambda options permet la configuration d’un certificat X.509 :

public static void Main(string[] args)
{
    CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(serverOptions =>
            {
                serverOptions.Listen(IPAddress.Loopback, 5000);
                serverOptions.Listen(IPAddress.Loopback, 5001, 
                    listenOptions =>
                    {
                        listenOptions.UseHttps("testCert.pfx", 
                            "testPassword");
                    });
            })
            .UseStartup<Startup>();
        });

L’exemple configure HTTPS pour un point de terminaison avec ListenOptions. Utilisez la même API afin de configurer d’autres paramètres Kestrel pour des points de terminaison spécifiques.

Pour créer des certificats auto-signés sous Windows, vous pouvez utiliser l’applet de commande PowerShell New-SelfSignedCertificate. Pour obtenir un exemple non pris en charge, consultez UpdateIISExpressSSLForChrome.ps1.

OpenSSL permet de créer des certificats sous macOS, Linux et Windows.

Lier à un socket Unix

Écoutez sur un socket Unix avec ListenUnixSocket pour améliorer les performances avec Nginx, comme illustré dans cet exemple :

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock", 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testpassword");
        });
})
  • Dans le fichier de configuration Nginx, définissez l’entrée server>location>proxy_pass sur http://unix:/tmp/{KESTREL SOCKET}:/;. {KESTREL SOCKET} est le nom du socket fourni à ListenUnixSocket (par exemple, kestrel-test.sock dans l’exemple précédent).
  • Vérifiez que le socket est accessible en écriture par Nginx (par exemple, chmod go+w /tmp/kestrel-test.sock).

Port 0

Si vous spécifiez le numéro de port 0, Kestrel se lie dynamiquement à un port disponible. L’exemple suivant montre comment déterminer le port auquel Kestrel se lie au moment de l’exécution :

public void Configure(IApplicationBuilder app)
{
    var serverAddressesFeature =
        app.ServerFeatures.Get<IServerAddressesFeature>();

    app.UseStaticFiles();

    app.Run(async (context) =>
    {
        context.Response.ContentType = "text/html";
        await context.Response
            .WriteAsync("<!DOCTYPE html><html lang=\"en\"><head>" +
                "<title></title></head><body><p>Hosted by Kestrel</p>");

        if (serverAddressesFeature != null)
        {
            await context.Response
                .WriteAsync("<p>Listening on the following addresses: " +
                    string.Join(", ", serverAddressesFeature.Addresses) +
                    "</p>");
        }

        await context.Response.WriteAsync("<p>Request URL: " +
            $"{context.Request.GetDisplayUrl()}<p>");
    });
}

Quand l’application est exécutée, la sortie de la fenêtre de console indique le port dynamique où l’application peut être atteinte :

Listening on the following addresses: http://127.0.0.1:48508

Limitations

Configurez des points de terminaison avec les approches suivantes :

  • UseUrls
  • Arguments de ligne de commande --urls
  • La clé de configuration d’hôte urls
  • ASPNETCORE_URLS variable d’environnement

Ces méthodes sont utiles si vous voulez que votre code fonctionne avec des serveurs autres que Kestrel. Toutefois, soyez conscient des limitations suivantes :

  • HTTPS ne peut pas être utilisé avec ces approches, sauf si un certificat par défaut est fourni dans la configuration du point de terminaison HTTPS (par exemple avec la configuration KestrelServerOptions ou un fichier de configuration, comme illustré plus haut dans cet article).
  • Quand les deux approches Listen et UseUrls sont utilisées simultanément, les points de terminaison Listen remplacent les points de terminaison UseUrls.

Configuration de point de terminaison IIS

Quand vous utilisez IIS, les liaisons d’URL pour IIS remplacent les liaisons qui sont définies par Listen ou par UseUrls. Pour plus d’informations, consultez Module ASP.NET Core.

ListenOptions.Protocols

La propriété Protocols établit les protocoles HTTP (HttpProtocols) activés sur un point de terminaison de connexion ou pour le serveur. Affectez une valeur à la propriété Protocols à partir de l’énumération HttpProtocols.

Valeur enum HttpProtocols Protocole de connexion autorisé
Http1 HTTP/1.1 uniquement. Peut être utilisé avec ou sans TLS.
Http2 HTTP/2 uniquement. Peut être utilisé sans TLS, uniquement si le client prend en charge un mode de connaissance préalable (Prior Knowledge).
Http1AndHttp2 HTTP/1.1 et HTTP/2. HTTP/2 nécessite que le client sélectionne HTTP/2 dans l’établissement d’une liaison TLS ALPN (Application-Layer Protocol Negotiation) ; sinon, la connexion est établie par défaut sur HTTP/1.1.

La valeur ListenOptions.Protocols par défaut pour n’importe quel point de terminaison est HttpProtocols.Http1AndHttp2.

Restrictions TLS pour HTTP/2 :

  • TLS version 1.2 ou ultérieure
  • Renégociation désactivée
  • Compression désactivée
  • Tailles minimales de l’échange de clé éphémère :
    • Diffie-Hellman à courbe elliptique (ECDHE) [RFC4492] : 224 bits minimum
    • Diffie-Hellman à champ fini (DHE) [TLS12] : 2048 bits minimum
  • Suite de chiffrement non interdite.

Prise en charge par défaut de TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] avec la courbe elliptique P-256 [FIPS186].

L’exemple suivant autorise les connexions HTTP/1.1 et HTTP/2 sur le port 8000. Les connexions sont sécurisées par TLS avec un certificat fourni :

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

Sur Linux, CipherSuitesPolicy peut être utilisé pour filtrer les établissements de liaisons TLS par connexion :

// using System.Net.Security;
// using Microsoft.AspNetCore.Hosting;
// using Microsoft.AspNetCore.Server.Kestrel.Core;
// using Microsoft.Extensions.DependencyInjection;
// using Microsoft.Extensions.Hosting;

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.OnAuthenticate = (context, sslOptions) =>
        {
            sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
                new[]
                {
                    TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                    TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
                    // ...
                });
        };
    });
});

Intergiciel de connexion

L’intergiciel de connexion personnalisé peut filtrer l’établissement de liaisons TLS par connexion pour des chiffrements spécifiques si nécessaire.

L’exemple suivant renvoie NotSupportedException pour tout algorithme de chiffrement que l’application ne prend pas en charge. Vous pouvez également définir et comparer ITlsHandshakeFeature.CipherAlgorithm à une liste de suites de chiffrement acceptables.

Aucun chiffrement n’est utilisé avec un algorithme de chiffrement CipherAlgorithmType.Null.

// using System.Net;
// using Microsoft.AspNetCore.Connections;

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.UseTlsFilter();
    });
});
using System;
using System.Security.Authentication;
using Microsoft.AspNetCore.Connections.Features;

namespace Microsoft.AspNetCore.Connections
{
    public static class TlsFilterConnectionMiddlewareExtensions
    {
        public static IConnectionBuilder UseTlsFilter(
            this IConnectionBuilder builder)
        {
            return builder.Use((connection, next) =>
            {
                var tlsFeature = connection.Features.Get<ITlsHandshakeFeature>();

                if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
                {
                    throw new NotSupportedException("Prohibited cipher: " +
                        tlsFeature.CipherAlgorithm);
                }

                return next();
            });
        }
    }
}

Le filtrage de connexion peut également être configuré via un lambda IConnectionBuilder :

// using System;
// using System.Net;
// using System.Security.Authentication;
// using Microsoft.AspNetCore.Connections;
// using Microsoft.AspNetCore.Connections.Features;

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.Use((context, next) =>
        {
            var tlsFeature = context.Features.Get<ITlsHandshakeFeature>();

            if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
            {
                throw new NotSupportedException(
                    $"Prohibited cipher: {tlsFeature.CipherAlgorithm}");
            }

            return next();
        });
    });
});

Définissez le protocole HTTP à partir de la configuration

Par défaut, CreateDefaultBuilder appelle serverOptions.Configure(context.Configuration.GetSection("Kestrel")) pour charger la configuration Kestrel.

L’exemple appsettings.json suivant établit HTTP/1.1 comme protocole de connexion par défaut pour tous les points de terminaison :

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1"
    }
  }
}

L’exemple appsettings.json suivant établit le protocole de connexion HTTP/1.1 pour un point de terminaison spécifique :

{
  "Kestrel": {
    "Endpoints": {
      "HttpsDefaultCert": {
        "Url": "https://localhost:5001",
        "Protocols": "Http1"
      }
    }
  }
}

Les protocoles spécifiés dans le code remplacent les valeurs définies par configuration.

Préfixes d’URL

Quand vous utilisez UseUrls, l’argument de ligne de commande --urls, la clé de configuration d’hôte urls ou la variable d’environnement ASPNETCORE_URLS, les préfixes d’URL peuvent être dans un des formats suivants.

Seuls les préfixes d’URL HTTP sont valides. Kestrel ne prend pas en charge HTTPS lors de la configuration de liaisons d’URL à l’aide de UseUrls.

  • Adresse IPv4 avec numéro de port

    http://65.55.39.10:80/
    

    0.0.0.0 est un cas spécial qui se lie à toutes les adresses IPv4.

  • Adresse IPv6 avec numéro de port

    http://[0:0:0:0:0:ffff:4137:270a]:80/
    

    [::] est l’équivalent IPv6 de 0.0.0.0 dans IPv4.

  • Nom d’hôte avec numéro de port

    http://contoso.com:80/
    http://*:80/
    

    Les noms d’hôte, * et + ne sont pas spéciaux. Tout ce qui n’est pas reconnu comme adresse IP valide ou localhost se lie à toutes les adresses IP IPv4 et IPv6. Pour lier différents noms d’hôte à différentes applications ASP.NET Core sur le même port, utilisez HTTP.sys ou un serveur proxy inverse. Les exemples de serveur proxy inverse incluent IIS, Nginx ou Apache.

    Avertissement

    L’hébergement dans une configuration de proxy inverse nécessite le filtrage d’hôte.

  • Nom localhost de l’hôte avec numéro de port ou adresse IP de bouclage avec numéro de port

    http://localhost:5000/
    http://127.0.0.1:5000/
    http://[::1]:5000/
    

    Quand localhost est spécifié, Kestrel tente de se lier aux interfaces de bouclage IPv4 et IPv6. Si le port requis est en cours d’utilisation par un autre service sur l’une des interfaces de bouclage, Kestrel ne démarre pas. Si l’une des interfaces de bouclage n’est pas disponible pour une raison quelconque (généralement du fait de la non-prise en charge d’IPv6), Kestrel journalise un avertissement.