Zarządzanie sekretami w aplikacjach, szczególnie w środowisku lokalnym, jest kluczowe dla ochrony wrażliwych danych, takich jak klucze API czy poświadczenia do baz danych. Poprawne przechowywanie sekretów, bez umieszczania ich bezpośrednio w kodzie źródłowym aplikacji, zapobiega potencjalnym wyciekom informacji i zwiększa bezpieczeństwo całej infrastruktury. Narzędzie Secret Manager, dostępne w ramach .NET Core SDK, stanowi praktyczne rozwiązanie w tym zakresie i nie wymaga dodatkowej instalacji, jeśli SDK jest już zainstalowane.

Aby rozpocząć korzystanie z narzędzia Secret Manager, należy najpierw zainicjować przechowywanie sekretów w projekcie. W tym celu należy przejść do katalogu projektu, który wcześniej omawialiśmy, a następnie uruchomić w terminalu polecenie:

csharp
dotnet user-secrets init

To polecenie dodaje element UserSecretsId do pliku .csproj, który unikalnie identyfikuje sekrety tego projektu. Można to zweryfikować, otwierając plik .csproj w edytorze kodu, gdzie widać nowo dodany element UserSecretsId.

Kolejnym krokiem jest skonfigurowanie ciągu połączenia do bazy danych SQL Server. W tym celu należy dodać odpowiedni sekret za pomocą polecenia:

sql
dotnet user-secrets set "ConnectionStrings:BankingDbContext" "TWOJE POŁĄCZENIE DO BAZY DANYCH"

Jest to dobry moment, aby zrozumieć konwencję nazewnictwa sekretów. W przypadku ASP.NET Core 9, dla zachowania logicznego porządku, używa się dwukropków (:) do oddzielenia różnych poziomów hierarchii w nazwach sekretów. Na przykład, w pliku appsettings.json mamy sekcję:

json
"ConnectionStrings": { "BankingDbContext": "..." }

Oznacza to, że sekret będzie miał nazwę ConnectionStrings:BankingDbContext, gdzie ConnectionStrings to kategoria główna, a BankingDbContext to rzeczywisty klucz zawierający sekret - w tym przypadku ciąg połączenia z bazą danych SQL Server. Taka notacja pomaga w organizacji kluczy w sposób logiczny i zgodny z konfiguracją systemu ASP.NET Core 9, bez konieczności zmiany kodu aplikacji.

Warto także zaznaczyć, że w przypadku używania zmiennych środowiskowych w systemach operacyjnych, które nie pozwalają na stosowanie dwukropków w nazwach zmiennych, dwukropki są zastępowane podwójnymi podkreśleniami (__). Dla przykładu, w produkcyjnym środowisku zmienna środowiskowa, która odpowiada temu sekretowi, wyglądałaby następująco:

nginx
ConnectionStrings__BankingDbContext

Dzięki temu system konfiguracji ASP.NET Core 9 będzie w stanie poprawnie odczytać i zrekonstruować hierarchię kluczy zdefiniowanych w zmiennych środowiskowych, traktując je w sposób analogiczny do sekretów zdefiniowanych w appsettings.json lub za pomocą narzędzia Secret Manager.

Wszystkie sekrety przechowywane za pomocą narzędzia Secret Manager są zapisane na poziomie systemu operacyjnego, co oznacza, że nie będą one współdzielone z zewnętrznymi repozytoriami kodu źródłowego, co zapewnia dodatkową warstwę bezpieczeństwa. Można również zarządzać tymi sekretami, wykorzystując polecenia, takie jak:

  • Aby wyświetlić listę wszystkich sekretów na lokalnej maszynie:

sql
dotnet user-secrets list
  • Aby usunąć konkretny sekret:

arduino
dotnet user-secrets remove "ConnectionStrings:BankingDbContext"
  • Aby usunąć wszystkie sekrety:

arduino
dotnet user-secrets clear

Należy pamiętać, że narzędzie Secret Manager zostało zaprojektowane z myślą o środowiskach deweloperskich. W przypadku środowisk produkcyjnych należy zastosować bardziej zaawansowane rozwiązania, takie jak Azure Key Vault, AWS Secrets Manager lub inne bezpieczne systemy przechowywania wrażliwych danych konfiguracyjnych.

Zarządzanie sekretami to jednak tylko jedna z wielu kwestii dotyczących bezpieczeństwa aplikacji. Istotnym aspektem jest również stosowanie HTTPS oraz odpowiednia konfiguracja polityk CORS, co zapewnia bezpieczeństwo przesyłanych danych i uniemożliwia nieautoryzowany dostęp do zasobów aplikacji.

Wymuszenie HTTPS jest kluczowe dla zapewnienia bezpiecznej komunikacji między klientami a serwerami, chroniąc dane przesyłane przez sieć. ASP.NET Core 9 zapewnia wbudowane wsparcie dla wymuszenia HTTPS poprzez dodanie następującej linii kodu do pliku Program.cs:

csharp
app.UseHttpsRedirection();

Warto pamiętać, że dodanie tego middleware do aplikacji to tylko część procesu. Konieczne jest również skonfigurowanie serwera webowego (np. IIS, NGINX, Azure App Services), który będzie wymuszał użycie HTTPS oraz zapewni odpowiedni certyfikat SSL/TLS od zaufanego dostawcy certyfikatów.

Równie ważnym aspektem jest konfiguracja polityk CORS, które są implementowane przez przeglądarki w celu ograniczenia dostępu aplikacji webowych do zasobów na innych domenach, bez wyraźnego zezwolenia. W typowych aplikacjach SPA (Single Page Application) korzystających z technologii takich jak Angular, React, czy czysty JavaScript, zapytania HTTP wykonywane są w przeglądarce. Przeglądarka, stosując mechanizm CORS, nie pozwala na wysyłanie zapytań z jednej domeny do innej, chyba że ta druga domena wyraźnie zezwoli na takie zapytanie.

ASP.NET Core 9 pozwala na konfigurację polityk CORS, dzięki czemu można precyzyjnie określić, które domeny, nagłówki i metody mają być dozwolone. Oto przykład kodu w pliku Program.cs, który konfiguruje politykę CORS:

csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages(); builder.Services.AddCors(options => { options.AddPolicy("AllowSpecificOrigin", builder => { builder.WithOrigins("https://myapp.com") .AllowAnyHeader() .AllowAnyMethod(); }); }); var app = builder.Build(); app.UseHttpsRedirection(); app.UseCors("AllowSpecificOrigin"); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapRazorPages(); app.Run();

Dzięki takiej konfiguracji aplikacja będzie przyjmować zapytania tylko z określonej domeny, co znacząco podnosi poziom bezpieczeństwa.

Jak opublikować aplikację ASP.NET Core 9 w chmurze Azure z wykorzystaniem App Service i Azure SQL?

Publikacja aplikacji ASP.NET Core 9 w środowisku chmurowym Azure przynosi wymierne korzyści, pozwalając skupić się na kontekście aplikacyjnym i celach biznesowych, eliminując konieczność zarządzania infrastrukturą. Azure, jako kompleksowa platforma chmurowa, dostarcza dynamiczne zasoby umożliwiające obsługę zróżnicowanych obciążeń, zapewnienie dostępności oraz zabezpieczeń, a także ciągłe dostarczanie wartości dzięki elastycznym modelom wdrożeń.

Do wdrożenia aplikacji użyjemy zasobu typu App Service — platformy jako usługi (PaaS), która zapewnia kompletną infrastrukturę do hostowania aplikacji, jednocześnie eliminując potrzebę zarządzania serwerami, systemami operacyjnymi czy środowiskami uruchomieniowymi. App Service udostępnia nie tylko gotowe środowisko uruchomieniowe, ale również publiczny URL umożliwiający dostęp do wdrożonej aplikacji.

Pierwszym krokiem jest zalogowanie się do portalu Azure i utworzenie nowego zasobu Web App. W trakcie konfiguracji należy wskazać subskrypcję, grupę zasobów (np. rg-aspnet-core8) oraz unikalną nazwę aplikacji (urlshortener). Wybieramy typ publikacji jako Code, środowisko uruchomieniowe jako .NET 9 (LTS), system operacyjny Linux, a region wdrożeniowy jako East US 2. Plan taryfowy określamy jako Basic B1, co w zupełności wystarcza do celów demonstracyjnych.

Po konfiguracji podstawowych parametrów tworzymy również bazę danych — istotny element aplikacji UrlShortener. Wykorzystujemy zasób Azure SQL Server, który pozwala na hostowanie wielu baz danych. Tworzona baza będzie służyć do przechowywania zmapowanych adresów URL. W dalszej części procesu konfiguracji, wyłączamy Application Insights, ponieważ na etapie testowym monitoring nie jest kluczowy — można go dodać później w środowisku produkcyjnym.

Po zatwierdzeniu konfiguracji i utworzeniu zasobów, Azure przypisuje aplikacji domyślny adres URL, umożliwiający natychmiastowy dostęp do wdrożonej instancji. Niemniej jednak, aplikacja nie została jeszcze fizycznie wdrożona — serwer działa, ale musimy przeprowadzić proces publikacji pakietu aplikacji oraz konfiguracji bazy danych.

Ważnym etapem jest przygotowanie bazy danych — tabela do przechowywania skróconych adresów URL musi zostać utworzona z wykorzystaniem migracji Entity Framework Core. Trzeba jednak pamiętać, że usługa bazy danych w Azure jest domyślnie niedostępna publicznie ze względów bezpieczeństwa. Konieczne będzie wprowadzenie zmian w konfiguracji sieciowej, by umożliwić komunikację z bazą danych z zewnątrz (np. z maszyny deweloperskiej lub agenta CI/CD).

Wdrożenie aplikacji na App Service wymaga przygotowania opublikowanego pakietu — plików wynikowych aplikacji zbudowanej lokalnie lub przez pipeline CI. Pakiet ten można przesłać do Azure za pomo