Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Den här guiden visar hur du använder Microsoft. Identity.Web-tokencache och certifikatpaket med MSAL.NET i .NET Framework, .NET Standard 2.0 och klassiska .NET-program (.NET 4.7.2+).
Förstå översikten
Från och med Microsoft.Identity.Web 1.17+ kan du använda Microsoft.Identity.Web-verktygspaket med MSAL.NET i miljöer som inte är ASP.NET Core.
Identifiera paketfördelar
| Feature | Förmån |
|---|---|
| Tokencache-serialisering | Återanvändbara cacheadaptrar för minnesintern användning, SQL Server, Redis, Cosmos DB, PostgreSQL |
| Certifikathanterare | Förenklad inläsning av certifikat från KeyVault-, filsystem- eller certifikatarkiv |
| Anspråkstillägg | Verktygsmetoder för ClaimsPrincipal manipulering |
| .NET Standard 2.0 | Kompatibel med .NET Framework 4.7.2+, .NET Core och .NET 5+ |
| Minimala beroenden | Riktade paket utan ASP.NET Core-beroenden |
Granska scenarier som stöds
Följande scenarier stöds med målverktygspaketen.
- .NET Framework Console Applications (daemon-scenarier)
- Desktop Applications (.NET Framework)
- Worker Services (.NET Framework)
- .NET Standard 2.0-bibliotek (plattformsoberoende kompatibilitet)
- Non-web MSAL.NET-applikationer
Anmärkning
Information om ASP.NET MVC/webb-API-program finns i OWIN-integrering i stället.
Välj paket
Välj det paket som matchar ditt scenario.
Identifiera kärnpaket för MSAL.NET
| Package | Avsikt | Beroenden | .NET mål |
|---|---|---|---|
| Microsoft. Identity.Web.TokenCache | Serialiserare för tokencache, ClaimsPrincipal tillägg |
Minimal | .NET Standard 2.0 |
| Microsoft. Identity.Web.Certificate | Verktyg för certifikatinläsning | Minimal | .NET Standard 2.0 |
Installera paket
Använd någon av följande metoder för att lägga till paketen i projektet.
Správca balíkov 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
Förstå grundläggande paketbegränsningar
Kärnpaketet Microsoft.Identity.Web innehåller ASP.NET Core beroenden (Microsoft.AspNetCore.*), som:
- Är inte kompatibla med ASP.NET Framework
- Öka paketstorleken i onödan
- Skapa beroendekonflikter
Använd målpaket i stället för scenarier med .NET Framework och .NET Standard.
Konfigurera tokencache-serialisering
Förstå tokencacheadaptrar
Microsoft.Identity.Web tillhandahåller token-cacheadapter som fungerar sömlöst med MSAL.NET IConfidentialClientApplication.
Skapa en konfidentiell klient med tokencache
I följande exempel skapas ett konfidentiellt klientprogram och en minnesintern tokencache bifogas.
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;
}
}
Välj alternativ för token-cache
Välj den cacheprovider som passar bäst för distributionsscenariot.
Konfigurera minnesintern tokencache
I följande exempel läggs ett enkelt minnesinternt cacheminne till:
using Microsoft.Identity.Web.TokenCacheProviders;
_app.AddInMemoryTokenCache();
Minnescache med storleksbegränsningar (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
});
});
Karakteristika:
- Snabb åtkomst
- Inga externa beroenden
- Delas inte mellan processer
- Förlorade vid omstart av app
Användningsfall: Konsolappar med en instans, skrivbordsprogram
Konfigurera distribuerad minnesintern tokencache
Använd följande kod för att lägga till en distribuerad minnesintern cache för miljöer med flera instanser:
_app.AddDistributedTokenCaches(services =>
{
// Requires: Microsoft.Extensions.Caching.Memory (NuGet)
services.AddDistributedMemoryCache();
});
Karakteristika:
- Delas mellan appinstanser
- Bättre för belastningsutjämningsscenarier
- Kräver ytterligare NuGet-paket
- Fortfarande förlorad vid omstart av appen
Användningsfall: Tjänster för flera instanser med acceptabel tokenåterhämtning
Konfigurera SQL Server token-cache
Använd följande kod för att lägga till en beständig, distribuerad SQL Server cache:
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);
});
});
Kör följande SQL för att skapa den nödvändiga cachetabellen:
-- 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]);
Karakteristika:
- Beständiga över omstarter
- Delas mellan flera instanser
- Tillförlitlig och skalbar
- Kräver SQL Server konfiguration
Användningsfall: Produktionsdaemontjänster, schemalagda uppgifter, arbetare med flera instanser
Konfigurera Redis-tokencache
Använd följande kod för att lägga till en redis-distribuerad cache med höga prestanda:
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_";
});
});
I följande exempel visas en produktionsklar Redis-konfiguration:
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
};
});
Karakteristika:
- Extremt snabb
- Delas mellan instanser
- Beständig (med Redis-persistens aktiverad)
- Kräver Redis-server
Användningsfall: Daemonappar med stora volymer, distribuerade system, mikrotjänster
Konfigurera Cosmos DB-tokencache
Använd följande kod för att lägga till en globalt distribuerad Cosmos DB-cache:
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;
});
});
Karakteristika:
- Globalt distribuerad
- Hög tillgänglighet
- Automatisk skalning
- Högre svarstid än Redis
- Högre kostnad
Användningsfall: Globala daemontjänster, geo-distribuerade program
Konfigurera PostgreSQL-tokencache
Använd följande kod för att lägga till en distribuerad PostgreSQL-cache:
_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);
});
});
Karakteristika:
- Beständiga över omstarter
- Delas mellan flera instanser
- Välbekant SQL-semantik
- Fungerar med Azure Database for PostgreSQL
- Kräver en PostgreSQL-server
Användningsfall: Program som redan använder PostgreSQL som primär databas eller tjänster som hostas på Azure och som använder Azure Database för PostgreSQL
Skapa ett fullständigt daemonprogram
I följande exempel visas ett fullständigt daemonprogram som hämtar token med klientautentiseringsuppgifter och en SQL Server tokencache.
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
}
}
}
Hantera certifikat
Förstå certifikatinläsning
Microsoft. Identity.Web förenklar certifikatinläsning från olika källor för autentiseringsflöden för klienter.
Läs in certifikat med DefaultCertificateLoader
I följande exempel visas hur du läser in ett certifikat från Azure Key Vault och skapar ett konfidentiellt klientprogram.
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;
}
}
Välj certifikatkällor
Läs in från Azure Key Vault
Läs in ett certifikat som lagras i Azure Key Vault genom att ange valvets URL och certifikatnamn.
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();
Förutsättningar:
- Hanterad identitet eller tjänsthuvudprincip med åtkomst till Key Vault
-
Azure.IdentityNuGet-paket - Key Vault-behörighet:
Getför certifikat
Läs in från certifikatslagringen
Läs in ett certifikat från Windows certifikatarkiv med unikt namn.
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();
Du kan också hitta ett certifikat med tumavtryck:
var certDescription = CertificateDescription.FromStoreWithThumbprint(
thumbprint: "ABCDEF1234567890ABCDEF1234567890ABCDEF12",
storeName: StoreName.My,
storeLocation: StoreLocation.LocalMachine
);
Läsa in från filsystemet
Läs in ett certifikat från en PFX-fil i det lokala filsystemet.
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();
Säkerhetsanteckning: Hårdkoda aldrig lösenord. Använd säker konfiguration.
Läsa in från Base64-kodad sträng
Läs in ett certifikat från en Base64-kodad sträng som lagras i konfigurationen.
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);
Konfigurera certifikatinläsning från App.config
Definiera certifikatinställningar i App.config-filen och läs in dem vid körning.
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>
Använd följande hjälpmetod för att läsa in certifikatet baserat på konfigurationen:
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")
};
}
Utforska exempelprogram
Granska de här exemplen för att se fungerande implementeringar.
Granska officiella Microsoft exempel
I följande tabell visas officiella exempel som visar cachelagring av token och inläsning av certifikat.
| Exempel | Plattform | Beskrivning |
|---|---|---|
| ConfidentialClientTokenCache | Konsol (.NET Framework) | Strategier för serialisering av token-cache |
| active-directory-dotnetcore-daemon-v2 | Konsol (.NET Core) | Certifikatinläsning från Key Vault |
Följ metodtipsen
Använd dessa mönster för att skapa tillförlitliga och säkra program.
Följ rekommenderade mönster
1. Använd singleton-mönstret för IConfidentialClientApplication:
Skapa en enda instans och återanvänd den i hela programmet.
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. Ange lämplig förfallotid för tokencache:
Konfigurera den glidande förfallotiden över tokenlivslängden för att förhindra onödiga nyförvärv.
// Access tokens typically expire after 1 hour
// Set cache expiration ABOVE token lifetime
options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
3. Använd säker certifikatlagring:
Lagra certifikat i Azure Key Vault eller ett korrekt skyddat certifikatarkiv.
// 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. Implementera korrekt felhantering:
Fånga MSAL-undantag och logga korrelations-ID:t för felsökning.
try
{
var result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
}
catch (MsalServiceException ex)
{
logger.Error($"Token acquisition failed. CorrelationId: {ex.CorrelationId}, ErrorCode: {ex.ErrorCode}");
throw;
}
5. Använd en distribuerad cache för produktion:
En distribuerad cache delar token mellan instanser och bevaras mellan omstarter.
// Correct for daemon services
app.AddDistributedTokenCaches(services =>
{
services.AddDistributedSqlServerCache(/* ... */);
});
Undvik vanliga misstag
1. Skapa inte nya IConfidentialClientApplication-instanser upprepade gånger:
// 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. Hårdkoda inte hemligheter:
// Wrong
.WithClientSecret("supersecretvalue123")
// Correct
.WithClientSecret(ConfigurationManager.AppSettings["AzureAd:ClientSecret"])
3. Använd inte minnesintern cache för tjänster med flera instanser:
// Wrong for services with multiple instances
app.AddInMemoryTokenCache();
// Correct - use distributed cache
app.AddDistributedTokenCaches(services =>
{
services.AddDistributedSqlServerCache(/* ... */);
});
4. Ignorera inte certifikatverifiering:
// Wrong - skips validation
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, errors) => true;
// Correct - validate certificates properly
Migrera från ADAL.NET
Granska de viktigaste skillnaderna och uppdatera koden så att den använder MSAL.NET med Microsoft. Identity.Web.
Förstå viktiga skillnader
| Aspekt | ADAL.NET (inaktuell) | MSAL.NET + Microsoft. Identity.Web |
|---|---|---|
| Scoper | Resursbaserad (https://graph.microsoft.com) |
Omfångsbaserad (https://graph.microsoft.com/.default) |
| Tokencache | Manuell serialisering krävs | Inbyggda adaptrar via tilläggsmetoder |
| Certificates | Manuell X509Certificate2-inläsning |
DefaultCertificateLoader med flera källor |
| Auktoritet | Fast vid konstruktion | Kan åsidosättas per begäran |
Jämför migreringsexempel
ADAL.NET (gammal):
AuthenticationContext authContext = new AuthenticationContext(authority);
ClientCredential credential = new ClientCredential(clientId, clientSecret);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, credential);
MSAL.NET med Microsoft. Identity.Web (Ny):
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();
Utforska relaterat innehåll
Använd dessa resurser för att lära dig mer om relaterade scenarier.