Najlepsze rozwiązania dotyczące wdrażania haseł i innych danych poufnych na platformie ASP.NET i w usłudze Azure App Service
Autor: Rick Anderson
W tym samouczku pokazano, jak kod może bezpiecznie przechowywać i uzyskiwać dostęp do bezpiecznych informacji. Najważniejszą kwestią jest to, że nigdy nie należy przechowywać haseł ani innych poufnych danych w kodzie źródłowym i nie należy używać wpisów tajnych produkcyjnych w trybie programowania i testowania.
Przykładowy kod to prosta aplikacja konsolowa zadania WebJob i aplikacja ASP.NET MVC, która wymaga dostępu do bazy danych parametry połączenia hasła, usług Twilio, Google i SendGrid bezpiecznych kluczy.
Wspomniano również o ustawieniach lokalnych i języku PHP.
- Praca z hasłami w środowisku projektowym
- Praca z parametry połączenia w środowisku projektowym
- Aplikacje konsolowe usługi WebJobs
- Wdrażanie wpisów tajnych na platformie Azure
- Uwagi dotyczące środowiska lokalnego i języka PHP
- Dodatkowe zasoby
Praca z hasłami w środowisku projektowym
Samouczki często pokazują poufne dane w kodzie źródłowym, miejmy nadzieję, że nie należy przechowywać poufnych danych w kodzie źródłowym. Na przykład moja aplikacja ASP.NET MVC 5 z wiadomościami SMS i pocztą e-mail 2FA zawiera następujące informacje w pliku web.config :
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<!-- Markup removed for clarity. -->
<!-- SendGrid-->
<add key="mailAccount" value="account" />
<add key="mailPassword" value="my password" />
<!-- Twilio-->
<add key="TwilioSid" value="My SID" />
<add key="TwilioToken" value="My Token" />
<add key="TwilioFromPhone" value="+12065551234" />
<add key="GoogClientID" value="1234.apps.googleusercontent.com" />
<add key="GoogClientSecret" value="My GCS" />
</appSettings>
<system.web>
Plik web.config jest kodem źródłowym, więc te wpisy tajne nigdy nie powinny być przechowywane w tym pliku. Na szczęście element ma file
atrybut, <appSettings>
który umożliwia określenie pliku zewnętrznego zawierającego poufne ustawienia konfiguracji aplikacji. Wszystkie wpisy tajne można przenieść do pliku zewnętrznego, o ile plik zewnętrzny nie jest zaewidencjonowany w drzewie źródłowym. Na przykład w następującym znaczniku plik AppSettingsSecrets.config zawiera wszystkie wpisy tajne aplikacji:
</connectionStrings>
<appSettings file="..\..\AppSettingsSecrets.config">
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<system.web>
Znaczniki w pliku zewnętrznym (AppSettingsSecrets.config w tym przykładzie) są tym samym znacznikami znajdującymi się w pliku web.config :
<appSettings>
<!-- SendGrid-->
<add key="mailAccount" value="My mail account." />
<add key="mailPassword" value="My mail password." />
<!-- Twilio-->
<add key="TwilioSid" value="My Twilio SID." />
<add key="TwilioToken" value="My Twilio Token." />
<add key="TwilioFromPhone" value="+12065551234" />
<add key="GoogClientID" value="1.apps.googleusercontent.com" />
<add key="GoogClientSecret" value="My Google client secret." />
</appSettings>
Środowisko uruchomieniowe ASP.NET scala zawartość pliku zewnętrznego z znacznikiem w <elemecie appSettings> . Środowisko uruchomieniowe ignoruje atrybut pliku, jeśli nie można odnaleźć określonego pliku.
Ostrzeżenie
Zabezpieczenia — nie dodawaj pliku config wpisów tajnych do projektu ani nie sprawdzaj go w kontroli źródła. Domyślnie program Visual Studio ustawia wartość Build Action
na Content
, co oznacza, że plik jest wdrażany. Aby uzyskać więcej informacji, zobacz Dlaczego nie wszystkie pliki w folderze projektu są wdrażane? Chociaż można użyć dowolnego rozszerzenia dla pliku config wpisów tajnych, najlepiej zachować plik config, ponieważ pliki konfiguracji nie są obsługiwane przez usługi IIS. Zwróć również uwagę, że plik AppSettingsSecrets.config ma dwa poziomy katalogu z pliku web.config , więc jest całkowicie poza katalogem rozwiązania. Przeniesienie pliku z katalogu rozwiązania "git add *" nie spowoduje dodania go do repozytorium.
Praca z parametry połączenia w środowisku projektowym
Program Visual Studio tworzy nowe projekty ASP.NET korzystające z bazy danych LocalDB. Baza danych LocalDB została utworzona specjalnie dla środowiska deweloperskiego. Nie wymaga to hasła, dlatego nie trzeba nic robić, aby zapobiec zaewidencjonowaniu wpisów tajnych w kodzie źródłowym. Niektóre zespoły programistyczne używają pełnych wersji programu SQL Server (lub innych systemów DBMS), które wymagają hasła.
Możesz użyć atrybutu configSource
, aby zastąpić cały <connectionStrings>
znacznik. W przeciwieństwie do atrybutu <appSettings>
file
, który scala znaczniki, configSource
atrybut zastępuje znaczniki. Poniższy znacznik pokazuje configSource
atrybut w pliku web.config :
<connectionStrings configSource="ConnectionStrings.config">
</connectionStrings>
Uwaga
Jeśli użyjesz atrybutuconfigSource
, jak pokazano powyżej, aby przenieść parametry połączenia do pliku zewnętrznego i utworzyć nową witrynę internetową programu Visual Studio, nie będzie można wykryć, że używasz bazy danych i nie będziesz mieć możliwości konfigurowania bazy danych podczas publikowania na platformie Azure z poziomu programu Visual Studio. Jeśli używasz atrybutu configSource
, możesz użyć programu PowerShell, aby utworzyć i wdrożyć witrynę internetową i bazę danych albo utworzyć witrynę internetową i bazę danych w portalu przed opublikowaniem.
Ostrzeżenie
Zabezpieczenia — w przeciwieństwie do pliku AppSettingsSecrets.config plik zewnętrznych parametry połączenia s musi znajdować się w tym samym katalogu co główny plik web.config, dlatego należy podjąć środki ostrożności, aby upewnić się, że nie zaewidencjonujesz go w repozytorium źródłowym.
Uwaga
Ostrzeżenie o zabezpieczeniach w pliku wpisów tajnych: najlepszym rozwiązaniem jest brak użycia wpisów tajnych produkcyjnych podczas testowania i programowania. Używanie haseł produkcyjnych w testach lub programach wycieka tych wpisów tajnych.
Aplikacje konsolowe usługi WebJobs
Plik app.config używany przez aplikację konsolową nie obsługuje ścieżek względnych, ale obsługuje ścieżki bezwzględne. Możesz użyć ścieżki bezwzględnej, aby przenieść wpisy tajne z katalogu projektu. Poniższy znacznik pokazuje wpisy tajne w pliku C:\secrets\AppSettingsSecrets.config i dane nieuwrażliwe w pliku app.config .
<configuration>
<appSettings file="C:\secrets\AppSettingsSecrets.config">
<add key="TwitterMaxThreads" value="24" />
<add key="StackOverflowMaxThreads" value="24" />
<add key="MaxDaysForPurge" value="30" />
</appSettings>
</configuration>
Wdrażanie wpisów tajnych na platformie Azure
Podczas wdrażania aplikacji internetowej na platformie Azure plik AppSettingsSecrets.config nie zostanie wdrożony (to jest to, co chcesz). Możesz przejść do portalu zarządzania Platformy Azure i ustawić je ręcznie, aby to zrobić:
- Przejdź do https://portal.azure.comstrony i zaloguj się przy użyciu poświadczeń platformy Azure.
- Kliknij pozycję Przeglądaj > aplikacje internetowe, a następnie kliknij nazwę aplikacji internetowej.
- Kliknij pozycję Wszystkie ustawienia Ustawienia> aplikacji.
Ustawienia aplikacji i parametry połączenia wartości zastępują te same ustawienia w pliku web.config. W naszym przykładzie nie wdrożyliśmy tych ustawień na platformie Azure, ale jeśli te klucze znajdowały się w pliku web.config, ustawienia wyświetlane w portalu miałyby pierwszeństwo.
Najlepszym rozwiązaniem jest wykonanie przepływu pracy metodyki DevOps i użycie programu Azure PowerShell (lub innej platformy, takiej jak Chef lub Puppet), aby zautomatyzować ustawianie tych wartości na platformie Azure. Poniższy skrypt programu PowerShell używa narzędzia Export-CliXml do eksportowania zaszyfrowanych wpisów tajnych na dysk:
param(
[Parameter(Mandatory=$true)]
[String]$Name,
[Parameter(Mandatory=$true)]
[String]$Password)
$credPath = $PSScriptRoot + '\' + $Name + ".credential"
$PWord = ConvertTo-SecureString –String $Password –AsPlainText -Force
$Credential = New-Object –TypeName `
System.Management.Automation.PSCredential –ArgumentList $Name, $PWord
$Credential | Export-CliXml $credPath
W powyższym skrypcie "Name" jest nazwą klucza tajnego, takiego jak "FB_AppSecret" lub "TwitterSecret". Plik ".credential" utworzony przez skrypt można wyświetlić w przeglądarce. Poniższy fragment kodu testuje każdy z plików poświadczeń i ustawia wpisy tajne dla nazwanej aplikacji internetowej:
Function GetPW_fromCredFile { Param( [String]$CredFile )
$Credential = GetCredsFromFile $CredFile
$PW = $Credential.GetNetworkCredential().Password
# $user just for debugging.
$user = $Credential.GetNetworkCredential().username
Return $PW
}
$AppSettings = @{
"FB_AppSecret" = GetPW_fromCredFile "FB_AppSecret.credential";
"GoogClientSecret" = GetPW_fromCredFile "GoogClientSecret.credential";
"TwitterSecret" = GetPW_fromCredFile "TwitterSecret.credential";
}
Set-AzureWebsite -Name $WebSiteName -AppSettings $AppSettings
Ostrzeżenie
Zabezpieczenia — nie uwzględniaj haseł ani innych wpisów tajnych w skrypcie programu PowerShell, co powoduje pokonanie celu użycia skryptu programu PowerShell w celu wdrożenia poufnych danych. Polecenie cmdlet Get-Credential zapewnia bezpieczny mechanizm uzyskiwania hasła. Użycie monitu interfejsu użytkownika może zapobiec wyciekowi hasła.
Wdrażanie parametry połączenia bazy danych
Parametry połączenia bazy danych są obsługiwane podobnie do ustawień aplikacji. Jeśli wdrożysz aplikację internetową z poziomu programu Visual Studio, zostanie skonfigurowana parametry połączenia. Możesz to sprawdzić w portalu. Zalecanym sposobem ustawienia parametry połączenia jest program PowerShell.
Uwagi dotyczące języka PHP
Ponieważ pary klucz-wartość zarówno dla ustawień aplikacji, jak i parametry połączenia są przechowywane w zmiennych środowiskowych w usłudze aplikacja systemu Azure, deweloperzy korzystający z dowolnych struktur aplikacji internetowych (takich jak PHP) mogą łatwo pobrać te wartości. Zobacz wpis w blogu Stefan Schackow's Windows Azure Web Sites: How Application Strings and Connection Strings Work (Jak parametry aplikacji i parametry połączenia działają), w którym przedstawiono fragment kodu PHP służący do odczytywania ustawień aplikacji i parametry połączenia.
Uwagi dotyczące serwerów lokalnych
Jeśli wdrażasz na lokalnych serwerach sieci Web, możesz pomóc zabezpieczyć wpisy tajne, szyfrując sekcje konfiguracji plików konfiguracji. Alternatywnie możesz użyć tego samego podejścia zalecanego dla usługi Azure Websites: zachować ustawienia programowania w plikach konfiguracji i użyć wartości zmiennych środowiskowych dla ustawień produkcyjnych. W takim przypadku należy jednak napisać kod aplikacji dla funkcji automatycznych w usłudze Azure Websites: pobierać ustawienia ze zmiennych środowiskowych i używać tych wartości zamiast ustawień pliku konfiguracji lub używać ustawień pliku konfiguracji, gdy zmienne środowiskowe nie zostaną znalezione.
Dodatkowe zasoby
Zobacz Witryny internetowe platformy Windows Azure w systemie Windows Schackow: Jak działają parametry aplikacji i parametry połączenia
Specjalne podziękowania barry Dorrans ( @blowdart ) i Carlos Farre do przeglądu.