Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
V této příručce se dozvíte, jak používat tokenovou mezipaměť Microsoft.Identity.Web a balíčky certifikátů s MSAL.NET v rozhraní .NET Framework, .NET Standard 2.0 a v klasických aplikacích .NET (.NET 4.7.2+).
Vysvětlení přehledu
Od verze Microsoft.Identity.Web 1.17+ můžete použít nástrojové balíčky Microsoft.Identity.Web s MSAL.NET v ne-ASP.NET Core prostředích.
Identifikace výhod balíčku
| funkce | Prospěch |
|---|---|
| Serializace mezipaměti tokenů | Opakovaně použitelné adaptéry mezipaměti pro paměťovou cache, SQL Server, Redis, Cosmos DB, PostgreSQL |
| Pomocníci certifikátů | Zjednodušené načítání certifikátů z úložišť klíčů KeyVault, systému souborů nebo certifikátů |
| Rozšíření nároků | Pomocné metody pro ClaimsPrincipal manipulaci |
| .NET Standard 2.0 | Kompatibilní s rozhraním .NET Framework 4.7.2+, .NET Core a .NET 5 nebo novějším |
| Minimální závislosti | Cílové balíčky bez ASP.NET Core závislostí |
Kontrola podporovaných scénářů
Následující scénáře jsou podporovány cílovými balíčky nástrojů.
- .NET Framework Console Applications (scénáře démona)
- Desktop Applications (.NET Framework)
- Worker Services (.NET Framework)
- knihovny .NET Standard 2.0 (kompatibilita mezi platformami)
- Newebové MSAL.NET aplikace
Poznámka:
Informace o aplikacích ASP.NET MVC/Web API najdete v tématu OWIN Integration.
Výběr balíčků
Zvolte balíček, který odpovídá vašemu scénáři.
Identifikace základních balíčků pro MSAL.NET
| Balíček | Purpose | Závislosti | cíl .NET |
|---|---|---|---|
| Microsoft. Identity.Web.TokenCache | Serializátory mezipaměti tokenů, ClaimsPrincipal rozšíření |
Minimální | .NET Standard 2.0 |
| Microsoft. Identity.Web.Certificate | Nástroje pro načítání certifikátů | Minimální | .NET Standard 2.0 |
Instalace balíčků
K přidání balíčků do projektu použijte jednu z následujících metod.
Správce balíčků Console:
# Token cache serialization
Install-Package Microsoft.Identity.Web.TokenCache
# Certificate management
Install-Package Microsoft.Identity.Web.Certificate
.NET CLI:
dotnet add package Microsoft.Identity.Web.TokenCache
dotnet add package Microsoft.Identity.Web.Certificate
Vysvětlení omezení základních balíčků
Základní balíček Microsoft.Identity.Web zahrnuje ASP.NET Core závislosti (Microsoft.AspNetCore.*), které:
- Nekompatibilní s rozhraním ASP.NET Framework
- Zbytečně zvětšovat velikost balíčku
- Vytváření konfliktů závislostí
Použijte raději cílové balíčky pro scénáře .NET Framework a .NET Standard.
Konfigurace serializace mezipaměti tokenů
Porozumění adaptérům mezipaměti tokenů
Microsoft.Identity.Web poskytuje adaptéry mezipaměti tokenů, které bezproblémově fungují s IConfidentialClientApplication MSAL.NET.
Vytvoření důvěrného klienta s mezipamětí tokenů
Následující příklad vytvoří důvěrnou klientskou aplikaci a připojí mezipaměť tokenů v paměti.
using Microsoft.Identity.Client;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.TokenCacheProviders;
public class MsalAppBuilder
{
private static IConfidentialClientApplication _app;
public static IConfidentialClientApplication BuildConfidentialClientApplication()
{
if (_app == null)
{
string clientId = ConfigurationManager.AppSettings["AzureAd:ClientId"];
string clientSecret = ConfigurationManager.AppSettings["AzureAd:ClientSecret"];
string tenantId = ConfigurationManager.AppSettings["AzureAd:TenantId"];
// Create the confidential client application
_app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithClientSecret(clientSecret)
.WithTenantId(tenantId)
.WithAuthority(AzureCloudInstance.AzurePublic, tenantId)
.Build();
// Add token cache serialization (choose one option below)
_app.AddInMemoryTokenCache();
}
return _app;
}
}
Volba možností mezipaměti tokenů
Vyberte poskytovatele mezipaměti, který nejlépe vyhovuje vašemu scénáři nasazení.
Konfigurace mezipaměti tokenů v paměti
Následující příklad přidá jednoduchou mezipaměť v paměti:
using Microsoft.Identity.Web.TokenCacheProviders;
_app.AddInMemoryTokenCache();
Mezipaměť v paměti s omezením velikosti (Microsoft.Identity.Web 1.20+):
using Microsoft.Extensions.Caching.Memory;
_app.AddInMemoryTokenCache(services =>
{
// Configure memory cache options
services.Configure<MemoryCacheOptions>(options =>
{
options.SizeLimit = 5000000; // 5 MB limit
});
});
Charakteristiky:
- Rychlý přístup
- Žádné externí závislosti
- Není sdílený mezi procesy
- Ztráta při restartování aplikace
Případ použití: Aplikace konzoly s jednou instancí, desktopové aplikace
Konfigurace mezipaměti tokenů distribuované v paměti
Pomocí následujícího kódu přidejte distribuovanou mezipaměť v paměti pro prostředí s více instancemi:
_app.AddDistributedTokenCaches(services =>
{
// Requires: Microsoft.Extensions.Caching.Memory (NuGet)
services.AddDistributedMemoryCache();
});
Charakteristiky:
- Sdílené mezi instancemi aplikací
- Lepší pro scénáře s vyrovnáváním zatížení
- Vyžaduje další balíček NuGet.
- Stále při restartování aplikace dochází ke ztrátě
Případ použití: Služby s více instancemi s přijatelným opětovným získáním tokenu
Konfigurace mezipaměti tokenů SQL Server
Pomocí následujícího kódu přidejte trvalou distribuovanou mezipaměť SQL Server:
using Microsoft.Extensions.Caching.SqlServer;
_app.AddDistributedTokenCaches(services =>
{
// Requires: Microsoft.Extensions.Caching.SqlServer (NuGet)
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = ConfigurationManager.ConnectionStrings["TokenCache"].ConnectionString;
options.SchemaName = "dbo";
options.TableName = "TokenCache";
// IMPORTANT: Set expiration above token lifetime
// Access tokens typically expire after 1 hour
options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
});
});
Spuštěním následujícího příkazu SQL vytvořte požadovanou tabulku mezipaměti:
-- Create the cache table
CREATE TABLE [dbo].[TokenCache] (
[Id] NVARCHAR(449) NOT NULL,
[Value] VARBINARY(MAX) NOT NULL,
[ExpiresAtTime] DATETIMEOFFSET NOT NULL,
[SlidingExpirationInSeconds] BIGINT NULL,
[AbsoluteExpiration] DATETIMEOFFSET NULL,
PRIMARY KEY ([Id])
);
-- Create index for performance
CREATE INDEX [Index_ExpiresAtTime] ON [dbo].[TokenCache] ([ExpiresAtTime]);
Charakteristiky:
- Trvalé při restartování
- Sdíleno napříč několika instancemi
- Spolehlivé a škálovatelné
- Vyžaduje nastavení SQL Server
Případ použití: Produkční démonové služby, naplánované úlohy, pracovníci s více instancemi
Konfigurace mezipaměti tokenů Redis
Pomocí následujícího kódu přidejte vysoce výkonnou distribuovanou mezipaměť Redis:
using StackExchange.Redis;
using Microsoft.Extensions.Caching.StackExchangeRedis;
_app.AddDistributedTokenCaches(services =>
{
// Requires: Microsoft.Extensions.Caching.StackExchangeRedis (NuGet)
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = ConfigurationManager.AppSettings["Redis:ConnectionString"];
options.InstanceName = "TokenCache_";
});
});
Následující příklad ukazuje konfiguraci Redis připravenou pro produkční prostředí:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = ConfigurationManager.AppSettings["Redis:ConnectionString"];
options.InstanceName = "MyDaemonApp_";
// Optional: Configure Redis options
options.ConfigurationOptions = new ConfigurationOptions
{
AbortOnConnectFail = false,
ConnectTimeout = 5000,
SyncTimeout = 5000
};
});
Charakteristiky:
- Extrémně rychlá
- Sdíleno mezi instancemi
- Trvalá (s povolenou persistentností Redis)
- Vyžaduje server Redis.
Případ použití: Vysokoobjemové daemon aplikace, distribuované systémy, mikroslužby
Konfigurace mezipaměti tokenů Cosmos DB
Pomocí následujícího kódu přidejte globálně distribuovanou mezipaměť Cosmos DB:
using Microsoft.Extensions.Caching.Cosmos;
_app.AddDistributedTokenCaches(services =>
{
// Requires: Microsoft.Extensions.Caching.Cosmos (preview)
services.AddCosmosCache(options =>
{
options.ContainerName = "TokenCache";
options.DatabaseName = "IdentityCache";
options.ClientBuilder = new CosmosClientBuilder(
ConfigurationManager.AppSettings["CosmosConnectionString"]);
options.CreateIfNotExists = true;
});
});
Charakteristiky:
- Globálně distribuovaná
- Vysoká dostupnost
- Automatické škálování
- Vyšší latence než Redis
- Vyšší náklady
Případ použití: Globální služby démona, geograficky distribuované aplikace
Konfigurace mezipaměti tokenů PostgreSQL
K přidání distribuované mezipaměti PostgreSQL použijte následující kód:
_app.AddDistributedTokenCaches(services =>
{
// Requires: Microsoft.Extensions.Caching.Postgres (NuGet)
services.AddDistributedPostgresCache(options =>
{
options.ConnectionString = ConfigurationManager.ConnectionStrings["PostgresCache"].ConnectionString;
options.SchemaName = ConfigurationManager.AppSettings["PostgresCache:SchemaName"];
options.TableName = ConfigurationManager.AppSettings["PostgresCache:TableName"];
options.CreateIfNotExists = bool.Parse(
ConfigurationManager.AppSettings["PostgresCache:CreateIfNotExists"] ?? "true");
// Set expiration above token lifetime.
// Access tokens typically expire after 1 hour.
options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
});
});
Charakteristiky:
- Trvalé při restartování
- Sdíleno napříč několika instancemi
- Známá sémantika SQL
- Funguje s Azure Database for PostgreSQL
- Vyžaduje server PostgreSQL.
Použití případu: Aplikace, které už jako primární databázi používají PostgreSQL, nebo služby hostované Azure pomocí Azure Database for PostgreSQL
Vytvořte kompletní aplikaci démona
Následující příklad ukazuje úplnou aplikaci démona, která získává tokeny pomocí přihlašovacích údajů klienta a mezipaměti tokenů SQL Server.
using Microsoft.Identity.Client;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.TokenCacheProviders;
using System;
using System.Threading.Tasks;
namespace DaemonApp
{
class Program
{
private static IConfidentialClientApplication _app;
static async Task Main(string[] args)
{
// Build confidential client with token cache
_app = BuildConfidentialClient();
// Acquire token for app-only access
string[] scopes = new[] { "https://graph.microsoft.com/.default" };
try
{
var result = await _app.AcquireTokenForClient(scopes)
.ExecuteAsync();
Console.WriteLine($"Token acquired successfully!");
Console.WriteLine($"Token source: {result.AuthenticationResultMetadata.TokenSource}");
Console.WriteLine($"Expires on: {result.ExpiresOn}");
// Use token to call API
await CallProtectedApi(result.AccessToken);
}
catch (MsalServiceException ex)
{
Console.WriteLine($"Error acquiring token: {ex.ErrorCode}");
Console.WriteLine($"CorrelationId: {ex.CorrelationId}");
}
}
private static IConfidentialClientApplication BuildConfidentialClient()
{
var app = ConfidentialClientApplicationBuilder
.Create(ConfigurationManager.AppSettings["ClientId"])
.WithClientSecret(ConfigurationManager.AppSettings["ClientSecret"])
.WithTenantId(ConfigurationManager.AppSettings["TenantId"])
.Build();
// Add SQL Server token cache for persistence
app.AddDistributedTokenCaches(services =>
{
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = ConfigurationManager
.ConnectionStrings["TokenCache"].ConnectionString;
options.SchemaName = "dbo";
options.TableName = "TokenCache";
options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
});
});
return app;
}
private static async Task CallProtectedApi(string accessToken)
{
// Your API call logic
}
}
}
Správa certifikátů
Principy načítání certifikátů
Microsoft. Identity.Web zjednodušuje načítání certifikátů z různých zdrojů pro toky přihlašovacích údajů klienta.
Načtení certifikátů pomocí DefaultCertificateLoader
Následující příklad ukazuje, jak načíst certifikát z Azure Key Vault a vytvořit důvěrnou klientskou aplikaci.
using Microsoft.Identity.Web;
using Microsoft.Identity.Client;
public class CertificateHelper
{
public static IConfidentialClientApplication CreateAppWithCertificate()
{
string clientId = ConfigurationManager.AppSettings["AzureAd:ClientId"];
string tenantId = ConfigurationManager.AppSettings["AzureAd:TenantId"];
// Define certificate source
var certDescription = CertificateDescription.FromKeyVault(
keyVaultUrl: "https://my-keyvault.vault.azure.net",
keyVaultCertificateName: "MyCertificate"
);
// Load certificate
ICertificateLoader certificateLoader = new DefaultCertificateLoader();
certificateLoader.LoadIfNeeded(certDescription);
// Create confidential client with certificate
var app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithCertificate(certDescription.Certificate)
.WithTenantId(tenantId)
.Build();
// Add token cache
app.AddInMemoryTokenCache();
return app;
}
}
Volba zdrojů certifikátů
Načtení z Azure Key Vault
Načtěte certifikát uložený v Azure Key Vault zadáním adresy URL trezoru a názvu certifikátu.
var certDescription = CertificateDescription.FromKeyVault(
keyVaultUrl: "https://my-keyvault.vault.azure.net",
keyVaultCertificateName: "MyApplicationCert"
);
ICertificateLoader loader = new DefaultCertificateLoader();
loader.LoadIfNeeded(certDescription);
var app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithCertificate(certDescription.Certificate)
.WithTenantId(tenantId)
.Build();
Požadavky:
- Spravovaná identita nebo instanční objekt s přístupem Key Vault
- balíček NuGet
Azure.Identity - oprávnění Key Vault:
Getu certifikátů
Načtení z úložiště certifikátů
Načtěte certifikát z úložiště certifikátů Windows podle jednoznačného názvu.
var certDescription = CertificateDescription.FromStoreWithDistinguishedName(
distinguishedName: "CN=MyApp.contoso.com",
storeName: StoreName.My,
storeLocation: StoreLocation.CurrentUser
);
ICertificateLoader loader = new DefaultCertificateLoader();
loader.LoadIfNeeded(certDescription);
var app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithCertificate(certDescription.Certificate)
.WithTenantId(tenantId)
.Build();
Certifikát můžete najít také kryptografickým otiskem:
var certDescription = CertificateDescription.FromStoreWithThumbprint(
thumbprint: "ABCDEF1234567890ABCDEF1234567890ABCDEF12",
storeName: StoreName.My,
storeLocation: StoreLocation.LocalMachine
);
Načtení ze systému souborů
Načtěte certifikát ze souboru PFX v místním systému souborů.
var certDescription = CertificateDescription.FromPath(
path: @"C:\Certificates\MyAppCert.pfx",
password: ConfigurationManager.AppSettings["Certificate:Password"]
);
ICertificateLoader loader = new DefaultCertificateLoader();
loader.LoadIfNeeded(certDescription);
var app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithCertificate(certDescription.Certificate)
.WithTenantId(tenantId)
.Build();
Poznámka k zabezpečení: Nikdy nezakódujte hesla. Použijte zabezpečenou konfiguraci.
Načíst z Base64 kódovaného řetězce
Načtěte certifikát z řetězce zakódovaného v Base64 uloženého v konfiguraci.
string base64Cert = ConfigurationManager.AppSettings["Certificate:Base64"];
var certDescription = CertificateDescription.FromBase64Encoded(
base64EncodedValue: base64Cert,
password: ConfigurationManager.AppSettings["Certificate:Password"] // Optional
);
ICertificateLoader loader = new DefaultCertificateLoader();
loader.LoadIfNeeded(certDescription);
Konfigurace načítání certifikátů z App.config
Definujte nastavení certifikátu v souboru App.config a načtěte je za běhu.
App.config:
<appSettings>
<add key="AzureAd:ClientId" value="your-client-id" />
<add key="AzureAd:TenantId" value="your-tenant-id" />
<!-- Option 1: KeyVault -->
<add key="Certificate:SourceType" value="KeyVault" />
<add key="Certificate:KeyVaultUrl" value="https://my-vault.vault.azure.net" />
<add key="Certificate:KeyVaultCertificateName" value="MyCert" />
<!-- Option 2: Store -->
<!--
<add key="Certificate:SourceType" value="StoreWithThumbprint" />
<add key="Certificate:CertificateThumbprint" value="ABCD..." />
<add key="Certificate:CertificateStorePath" value="CurrentUser/My" />
-->
</appSettings>
<connectionStrings>
<add name="TokenCache"
connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=TokenCache;Integrated Security=True;" />
</connectionStrings>
K načtení certifikátu na základě konfigurace použijte následující pomocnou metodu:
public static CertificateDescription GetCertificateFromConfig()
{
string sourceType = ConfigurationManager.AppSettings["Certificate:SourceType"];
return sourceType switch
{
"KeyVault" => CertificateDescription.FromKeyVault(
ConfigurationManager.AppSettings["Certificate:KeyVaultUrl"],
ConfigurationManager.AppSettings["Certificate:KeyVaultCertificateName"]
),
"StoreWithThumbprint" => CertificateDescription.FromStoreWithThumbprint(
ConfigurationManager.AppSettings["Certificate:CertificateThumbprint"],
StoreName.My,
StoreLocation.CurrentUser
),
_ => throw new ConfigurationErrorsException("Invalid certificate source type")
};
}
Prozkoumání ukázkových aplikací
Projděte si tyto ukázky a podívejte se na funkční implementace.
Projděte si oficiální ukázky Microsoft
Následující tabulka uvádí oficiální ukázky, které demonstrují ukládání tokenů do mezipaměti a načítání certifikátů.
| Ukázka | Platforma | Description |
|---|---|---|
| ConfidentialClientTokenCache | Konzola (.NET Framework) | Vzory serializace mezipaměti tokenů |
| active-directory-dotnetcore-daemon-v2 | Konzola (.NET Core) | Načítání certifikátů z Key Vault |
Dodržujte osvědčené postupy.
Tyto vzory použijte k vytváření spolehlivých a zabezpečených aplikací.
Postupujte podle doporučených vzorů.
1. Použijte singleton vzor pro IConfidentialClientApplication:
Vytvořte jednu instanci a znovu ji použijte v celé aplikaci.
private static IConfidentialClientApplication _app;
public static IConfidentialClientApplication GetApp()
{
if (_app == null)
{
_app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithClientSecret(clientSecret)
.WithTenantId(tenantId)
.Build();
_app.AddDistributedTokenCaches(/* ... */);
}
return _app;
}
2. Nastavte vypršení platnosti příslušné mezipaměti tokenů:
Nakonfigurujte posuvné vypršení platnosti nad životností tokenu, aby se zabránilo zbytečnému opětovnému získání.
// Access tokens typically expire after 1 hour
// Set cache expiration ABOVE token lifetime
options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
3. Použijte zabezpečené úložiště certifikátů:
Ukládejte certifikáty do Azure Key Vault nebo do správně zabezpečeného úložiště certifikátů.
// Azure Key Vault (production)
var cert = CertificateDescription.FromKeyVault(keyVaultUrl, certName);
// Certificate store with proper permissions
var cert = CertificateDescription.FromStoreWithThumbprint(
thumbprint, StoreName.My, StoreLocation.LocalMachine);
4. Implementace správného zpracování chyb:
Zachyťte výjimky MSAL a zalogujte ID korelace pro účely řešení problémů.
try
{
var result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
}
catch (MsalServiceException ex)
{
logger.Error($"Token acquisition failed. CorrelationId: {ex.CorrelationId}, ErrorCode: {ex.ErrorCode}");
throw;
}
5. Použijte distribuovanou mezipaměť pro produkční prostředí:
Distribuovaná mezipaměť sdílí tokeny mezi instancemi a zachovává je i po restartování.
// Correct for daemon services
app.AddDistributedTokenCaches(services =>
{
services.AddDistributedSqlServerCache(/* ... */);
});
Vyhněte se běžným chybám
1. Nevytvávejte nové instance IConfidentialClientApplication opakovaně:
// Wrong - creates new instance every time
public void AcquireToken()
{
var app = ConfidentialClientApplicationBuilder.Create(clientId).Build();
// ...
}
// Correct - use singleton
private static readonly IConfidentialClientApplication _app = BuildApp();
2. Nezakódujte tajné kódy:
// Wrong
.WithClientSecret("supersecretvalue123")
// Correct
.WithClientSecret(ConfigurationManager.AppSettings["AzureAd:ClientSecret"])
3. Nepoužívejte mezipaměť v paměti pro služby s více instancemi:
// Wrong for services with multiple instances
app.AddInMemoryTokenCache();
// Correct - use distributed cache
app.AddDistributedTokenCaches(services =>
{
services.AddDistributedSqlServerCache(/* ... */);
});
4. Neignorujte ověření certifikátu:
// Wrong - skips validation
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, errors) => true;
// Correct - validate certificates properly
Migrace z ADAL.NET
Projděte si klíčové rozdíly a aktualizujte kód tak, aby používal MSAL.NET s Microsoft. Identity.Web.
Vysvětlení klíčových rozdílů
| Aspekt | ADAL.NET (zastaralé) | MSAL.NET + Microsoft. Identity.Web |
|---|---|---|
| Rozsahy | Založené na prostředcích (https://graph.microsoft.com) |
Založené na rozsahu (https://graph.microsoft.com/.default) |
| Mezipaměť tokenů | Vyžaduje se ruční serializace | Integrované adaptéry prostřednictvím rozšiřujících metod |
| Certifikáty | Ruční načítání X509Certificate2 |
DefaultCertificateLoader s více zdroji |
| Autorita | Pevně nastaveno při výstavbě | Je možné přepsat na požadavek. |
Porovnání příkladů migrace
DAL.NET (starý):
AuthenticationContext authContext = new AuthenticationContext(authority);
ClientCredential credential = new ClientCredential(clientId, clientSecret);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, credential);
MSAL.NET s Microsoft. Identity.Web (nový):
var app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithClientSecret(clientSecret)
.WithTenantId(tenantId)
.Build();
app.AddInMemoryTokenCache(); // Add token cache
string[] scopes = new[] { "https://graph.microsoft.com/.default" };
AuthenticationResult result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
Prozkoumání souvisejícího obsahu
Další informace o souvisejících scénářích najdete v těchto zdrojích informací.
- Aplikace démona
- Integrace OWIN
- přehled architektury ASP.NET
- Přehled přihlašovacích údajů