| File: Repositories\DefaultKeyStorageDirectories.cs | Web Access |
| Project: src\aspnetcore\src\DataProtection\DataProtection\src\Microsoft.AspNetCore.DataProtection.csproj (Microsoft.AspNetCore.DataProtection) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; namespace Microsoft.AspNetCore.DataProtection.Repositories; internal sealed class DefaultKeyStorageDirectories : IDefaultKeyStorageDirectories { private static readonly Lazy<DirectoryInfo?> _defaultDirectoryLazy = new Lazy<DirectoryInfo?>(GetKeyStorageDirectoryImpl); private DefaultKeyStorageDirectories() { } public static IDefaultKeyStorageDirectories Instance { get; } = new DefaultKeyStorageDirectories(); /// <summary> /// The default key storage directory. /// On Windows, this currently corresponds to "Environment.SpecialFolder.LocalApplication/ASP.NET/DataProtection-Keys". /// On Linux and macOS, this currently corresponds to "$HOME/.aspnet/DataProtection-Keys". /// </summary> /// <remarks> /// This property can return null if no suitable default key storage directory can /// be found, such as the case when the user profile is unavailable. /// </remarks> public DirectoryInfo? GetKeyStorageDirectory() => _defaultDirectoryLazy.Value; private static DirectoryInfo? GetKeyStorageDirectoryImpl() { DirectoryInfo retVal; // Environment.GetFolderPath returns null if the user profile isn't loaded. var localAppDataFromSystemPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); var localAppDataFromEnvPath = Environment.GetEnvironmentVariable("LOCALAPPDATA"); var homePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !string.IsNullOrEmpty(localAppDataFromSystemPath)) { // To preserve backwards-compatibility with 1.x, Environment.SpecialFolder.LocalApplicationData // cannot take precedence over $LOCALAPPDATA and $HOME/.aspnet on non-Windows platforms retVal = GetKeyStorageDirectoryFromBaseAppDataPath(localAppDataFromSystemPath); } else if (localAppDataFromEnvPath != null) { retVal = GetKeyStorageDirectoryFromBaseAppDataPath(localAppDataFromEnvPath); } else if (homePath != null) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { retVal = GetKeyStorageDirectoryFromBaseAppDataPath(Path.Combine(homePath, "AppData", "Local")); } else { // Use*NIX conventions for a folder name. retVal = new DirectoryInfo(Path.Combine(homePath, ".aspnet", DataProtectionKeysFolderName)); } } else if (!string.IsNullOrEmpty(localAppDataFromSystemPath)) { // Starting in 2.x, non-Windows platforms may use Environment.SpecialFolder.LocalApplicationData // but only after checking for $LOCALAPPDATA, $USERPROFILE, and $HOME. retVal = GetKeyStorageDirectoryFromBaseAppDataPath(localAppDataFromSystemPath); } else { return null; } Debug.Assert(retVal != null); try { retVal.Create(); // throws if we don't have access, e.g., user profile not loaded return retVal; } catch { return null; } } public DirectoryInfo? GetKeyStorageDirectoryForAzureWebSites() { // Azure Web Sites needs to be treated specially, as we need to store the keys in a // correct persisted location. We use the existence of the %WEBSITE_INSTANCE_ID% env // variable to determine if we're running in this environment, and if so we then use // the %HOME% variable to build up our base key storage path. if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID"))) { var homeEnvVar = Environment.GetEnvironmentVariable("HOME"); if (!string.IsNullOrEmpty(homeEnvVar)) { return GetKeyStorageDirectoryFromBaseAppDataPath(homeEnvVar); } } // nope return null; } private const string DataProtectionKeysFolderName = "DataProtection-Keys"; private static DirectoryInfo GetKeyStorageDirectoryFromBaseAppDataPath(string basePath) { return new DirectoryInfo(Path.Combine(basePath, "ASP.NET", DataProtectionKeysFolderName)); } }