Upgrade ASP.NET aplikací z 6.0 na 7.0 je snadný a téměř bezpracný. Ve většině případů stačí jenom změnit verzi runtime v .csproj souboru a upgradovat NuGet balíčky. Ale můžete narazit na to, že se vám po upgrade databáze odmítne připojit k databázi s poněkud kryptickou chybou:

Unhandled exception. Microsoft.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0 - The certificate chain was issued by an authority that is not trusted.)

Hláška je to trochu matoucí, protože z ní na první pohled vyplývá, že je něco špatně s přihlašováním uživatele. Ale není to pravda. Ta důležitá informace se skrývá v následující zprávě, že se jedná o nedůvěryhodnou certifikační autoritu.

Nová verze balíčku Microsoft.Data.SqlClient (na níž závisí třeba Entity Framework Core) totiž ve výchozím nastavení používá šifrované připojení k SQL Serveru. Což je nepochybně myšlenka dobrá a z hlediska vyššího principu mravního správná. Problém ovšem je, že většina serverů nemá platný certifikát, ale používá dynamicky vygenerovaný self-signed. A klient na to reaguje právě shora zmíněnou chybou.

Dvě rychlá řešení

Nejrychlejší, ne ovšem nutně správná, řešení spočívají v prosté modifikaci connection stringu.

Váš stávající connection string vypadá nejspíše nějak takhle:

SERVER=.\SqlExpress;TRUSTED_CONNECTION=yes;DATABASE=Northwind

nebo:

Data Source=db.example.com,1433; Initial Catalog=Northwind;User ID=Northwind;Password=Pass.word123

Možných podob a kombinací je celá řada.

Symptomy shora uvedeného problému vyřešíte tak, že k connection stringu přidáte ;ENCRYPT=no nebo ;TRUSTSERVERCERTIFICATE=yes.

Jedno správné řešení

Popisovaná řešení nejsou správná. Jedná se o léčbu symptomů, nikoliv příčiny. Příčinou je nedůvěryhodný certifikát na straně serveru.

Certifikát můžete (z PFX nebo PEM souboru) nainstalovat pomocí nástroje Computer Management, viz následující obrázek:

Screenshot

Hraběcí rada

Ono správné řešení je ovšem poněkud hraběcí rada.

V první řadě, někdy je takový certifikát v podstatě nemožné od důvěryhodné autority získat, typicky pokud nepoužíváte pro připojení FQDN, ale lokální hostname, IP adresu nebo něco takového.

Ostatně nemusíme chodit daleko, třeba pro připojení k lokálnímu SQL Serveru Express na vývojářském stroji se jako název obvykle používá .\SqlExpress nebo (local)\SqlExpress a ani pro jedno z toho vám nikdo certifikát nevydá.

Obecně, pokud je databázový server a klient na jednom počítači (nekomunikují spolu po síti) není šifrované spojení z bezpečnostních důvodů nezbytné.

Další problém spočívá v tom, že se mi nepodařilo přijít na způsob, jak instalaci a aktualizaci serverového certifikátu automatizovat. Všechny návody počítají s nastavením pomocí GUI, jak bylo popsáno výše. Nepřišel jsem na to, jak tuto operaci udělat pomocí příkazové řádky nebo powershellu.

Pokud na takový způsob přijdete, dejte mi vědět, rád o tom napíšu článek nebo udělám video.

To prakticky vylučuje možnost použití bezplatných certifikátů od Let's Encrypt CA, které mají platnost pouze tři měsíce. A i komerční CA vám nevystaví certifikát na déle než rok.

Zbývá poslední cesta, a to vytvořit si vlastní CA a tu použít k vydání certifikátu s dlouhodobou platností. Nicméně krátká platnost certifikátů má své dobré důvody a provoz vlastní CA je ve většině případů cesta do pekel.