Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In deze handleiding ziet u hoe u de token cache en certificaatpakketten van Microsoft.Identity.Web met MSAL.NET kunt gebruiken in .NET Framework, .NET Standard 2.0 en klassieke .NET-toepassingen (.NET 4.7.2+).
Inzicht in het overzicht
Beginnend met Microsoft. Identity.Web 1.17+ kunt u Microsoft gebruiken. Identity.Web utility-pakketten met MSAL.NET in niet-ASP.NET Core omgevingen.
Pakketvoordelen identificeren
| Feature | Vergoeding |
|---|---|
| Serialisatie van tokencache | Herbruikbare cacheadapters voor in-memory, SQL Server, Redis, Cosmos DB, PostgreSQL |
| Helpers voor certificaten | Vereenvoudigd laden van certificaten vanuit KeyVault-, bestandssysteem- of certificaatarchieven |
| Claims-extensies | Hulpmethoden voor ClaimsPrincipal manipulatie |
| .NET Standard 2.0 | Compatibel met .NET Framework 4.7.2+, .NET Core en .NET 5+ |
| Minimale afhankelijkheden | Gerichte pakketten zonder ASP.NET Core afhankelijkheden |
Ondersteunde scenario's bekijken
De volgende scenario's worden ondersteund met de beoogde hulpprogrammapakketten.
- .NET Framework Console Applications (daemon-scenario's)
- Desktop-toepassingen (.NET Framework)
- Worker Services (.NET Framework)
- .NET Standard 2.0-bibliotheken (platformoverschrijdende compatibiliteit)
- Non-web-MSAL.NET-toepassingen
Opmerking
Zie OWIN Integration voor ASP.NET MVC/Web-API-toepassingen.
Pakketten selecteren
Kies het pakket dat overeenkomt met uw scenario.
Kernpakketten voor MSAL.NET identificeren
| Package | Purpose | Afhankelijkheden | .NET doel |
|---|---|---|---|
| Microsoft. Identity.Web.TokenCache | Tokencache-serializers, extensies voor ClaimsPrincipal |
Minimaal | .NET Standard 2.0 |
| Microsoft. Identity.Web.Certificate | Hulpprogramma's voor het laden van certificaten | Minimaal | .NET Standard 2.0 |
Pakketten installeren
Gebruik een van de volgende methoden om de pakketten toe te voegen aan uw project.
Pakketbeheer 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
Inzicht in basispakketbeperkingen
Het kernpakket Microsoft.Identity.Web bevat ASP.NET Core afhankelijkheden (Microsoft.AspNetCore.*), die:
- Zijn niet compatibel met ASP.NET Framework
- De pakketgrootte onnodig vergroten
- Afhankelijkheidsconflicten maken
Doelpakketten gebruiken voor .NET Framework- en .NET Standard-scenario's.
Serialisatie van tokencache configureren
Begrijp tokencacheadapters
Microsoft. Identity.Web biedt tokencacheadapters die naadloos werken met de IConfidentialClientApplication van MSAL.NET.
Een vertrouwelijke client bouwen met tokencache
In het volgende voorbeeld wordt een vertrouwelijke clienttoepassing gemaakt en wordt gekoppeld aan een tokencache in het geheugen.
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;
}
}
Opties voor tokencache kiezen
Selecteer de cacheprovider die het beste past bij uw implementatiescenario.
Tokencache in het geheugen configureren
In het volgende voorbeeld wordt een eenvoudige cache in het geheugen toegevoegd:
using Microsoft.Identity.Web.TokenCacheProviders;
_app.AddInMemoryTokenCache();
In-memory cache met groottelimieten (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
});
});
Kenmerken:
- Snelle toegang
- Geen externe afhankelijkheden
- Niet gedeeld tussen processen
- Verloren bij opnieuw opstarten van de app
Gebruikssituatie: Enkele instantie console-applicaties, desktoptoepassingen
Gedistribueerde tokencache in het geheugen configureren
Gebruik de volgende code om een gedistribueerde cache in het geheugen toe te voegen voor omgevingen met meerdere exemplaren:
_app.AddDistributedTokenCaches(services =>
{
// Requires: Microsoft.Extensions.Caching.Memory (NuGet)
services.AddDistributedMemoryCache();
});
Kenmerken:
- Gedeeld tussen app-instanties
- Beter voor scenario's met gelijke taakverdeling
- Vereist een extra NuGet-pakket
- Nog steeds verloren bij opnieuw opstarten van de app
Use case: Services met meerdere exemplaren met acceptabele tokenherwerving
SQL Server tokencache configureren
Gebruik de volgende code om een permanente, gedistribueerde SQL Server-cache toe te voegen:
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);
});
});
Voer de volgende SQL uit om de vereiste cachetabel te maken:
-- 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]);
Kenmerken:
- Permanent bij opnieuw opstarten
- Gedeeld over meerdere instanties
- Betrouwbaar en schaalbaar
- Vereist SQL Server-installatie
Use case: Productie daemon-services, geplande taken, werkrollen met meerdere exemplaren
Redis-tokencache configureren
Gebruik de volgende code om een gedistribueerde Redis-cache met hoge prestaties toe te voegen:
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_";
});
});
In het volgende voorbeeld ziet u een Redis-configuratie die gereed is voor productie:
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
};
});
Kenmerken:
- Zeer snel
- Gedeeld tussen instanties
- Persistent (met Redis-persistentie ingeschakeld)
- Vereist een Redis-server
Use case: Daemon-apps met grote volumes, gedistribueerde systemen, microservices
Cosmos DB-tokencache configureren
Gebruik de volgende code om een wereldwijd gedistribueerde Cosmos DB-cache toe te voegen:
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;
});
});
Kenmerken:
- Wereldwijd gedistribueerd
- Maximaal beschikbaar
- Automatisch schalen
- Hogere latentie dan Redis
- Hogere kosten
Use case: Wereldwijde daemon-services, geografisch gedistribueerde toepassingen
PostgreSQL-tokencache configureren
Gebruik de volgende code om een gedistribueerde PostgreSQL-cache toe te voegen:
_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);
});
});
Kenmerken:
- Permanent bij opnieuw opstarten
- Gedeeld over meerdere instanties
- Vertrouwde SQL-semantiek
- Werkt met Azure Database for PostgreSQL
- Vereist een PostgreSQL-server
Gebruiksvoorbeeld: Toepassingen maken al gebruik van PostgreSQL als primaire database of Azure gehoste services met behulp van Azure Database for PostgreSQL
Een volledige daemon-toepassing bouwen
In het volgende voorbeeld ziet u een volledige daemon-toepassing die tokens verkrijgt met behulp van clientreferenties en een 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
}
}
}
Certificaten beheren
Inzicht in het laden van certificaten
Microsoft. Identity.Web vereenvoudigt het laden van certificaten uit verschillende bronnen voor clientreferentiestromen.
Certificaten laden met DefaultCertificateLoader
In het volgende voorbeeld ziet u hoe u een certificaat uit Azure Key Vault laadt en een vertrouwelijke clienttoepassing maakt.
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;
}
}
Certificaatbronnen kiezen
Laden vanuit Azure Key Vault
Laad een certificaat dat is opgeslagen in Azure Key Vault door de kluis-URL en certificaatnaam op te geven.
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();
Voorwaarden:
- Beheerde identiteit of service-principal met toegang tot Key Vault
-
Azure.IdentityNuGet-pakket - Key Vault-toestemmingen:
Getvoor certificaten
Verladen vanuit certificaatopslag
Laad een certificaat uit de Windows certificaatopslag met een onderscheidende naam.
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();
U kunt ook een certificaat vinden via vingerafdruk:
var certDescription = CertificateDescription.FromStoreWithThumbprint(
thumbprint: "ABCDEF1234567890ABCDEF1234567890ABCDEF12",
storeName: StoreName.My,
storeLocation: StoreLocation.LocalMachine
);
Laden vanuit bestandssysteem
Laad een certificaat uit een PFX-bestand op het lokale bestandssysteem.
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();
Beveiligingsnotitie: Codeer nooit wachtwoorden. Veilige configuratie gebruiken.
Laden vanuit met Base64 gecodeerde tekenreeks
Laad een certificaat uit een met Base64 gecodeerde tekenreeks die is opgeslagen in de configuratie.
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);
Certificaat laden vanuit App.config configureren
Definieer certificaatinstellingen in uw App.config-bestand en laad deze tijdens runtime.
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>
Gebruik de volgende helpermethode om het certificaat te laden op basis van de configuratie:
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")
};
}
Voorbeeldtoepassingen verkennen
Bekijk deze voorbeelden om werkende implementaties te bekijken.
Officiële Microsoft voorbeelden bekijken
De volgende tabel bevat officiële voorbeelden die het laden van tokens in cache en het laden van certificaten demonstreren.
| voorbeeld | Platform | Beschrijving |
|---|---|---|
| ConfidentialClientTokenCache | Console (.NET Framework) | Serialisatiepatronen voor tokencache |
| active-directory-dotnetcore-daemon-v2 | Console (.NET Core) | Certificaat laden vanuit Key Vault |
Best practices volgen
Pas deze patronen toe om betrouwbare en veilige toepassingen te bouwen.
Aanbevolen patronen volgen
1. Gebruik het singleton-patroon voor IConfidentialClientApplication:
Maak één exemplaar en gebruik deze opnieuw in uw toepassing.
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. Stel de juiste verlooptijd van de tokencache in:
Configureer de verloopinstellingen zodanig dat deze langer zijn dan de levensduur van het token om onnodig opnieuw verkrijgen te voorkomen.
// Access tokens typically expire after 1 hour
// Set cache expiration ABOVE token lifetime
options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
3. Gebruik beveiligde certificaatopslag:
Sla certificaten op in Azure Key Vault of een correct beveiligd certificaatarchief.
// 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. De juiste foutafhandeling implementeren:
Onderschep MSAL-uitzonderingen en registreer de correlatie-id voor foutopsporing.
try
{
var result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
}
catch (MsalServiceException ex)
{
logger.Error($"Token acquisition failed. CorrelationId: {ex.CorrelationId}, ErrorCode: {ex.ErrorCode}");
throw;
}
5. Gebruik een gedistribueerde cache voor productie:
Een gedistribueerde cache deelt tokens tussen exemplaren en blijft behouden tijdens het opnieuw opstarten.
// Correct for daemon services
app.AddDistributedTokenCaches(services =>
{
services.AddDistributedSqlServerCache(/* ... */);
});
Veelvoorkomende fouten voorkomen
1. Maak niet herhaaldelijk nieuwe IConfidentialClientApplication-exemplaren:
// 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. Codeer geen geheimen:
// Wrong
.WithClientSecret("supersecretvalue123")
// Correct
.WithClientSecret(ConfigurationManager.AppSettings["AzureAd:ClientSecret"])
3. Gebruik geen cache in het geheugen voor services met meerdere exemplaren:
// Wrong for services with multiple instances
app.AddInMemoryTokenCache();
// Correct - use distributed cache
app.AddDistributedTokenCaches(services =>
{
services.AddDistributedSqlServerCache(/* ... */);
});
4. Negeer certificaatvalidatie niet:
// Wrong - skips validation
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, errors) => true;
// Correct - validate certificates properly
Migreren vanuit ADAL.NET
Bekijk de belangrijkste verschillen en werk uw code bij om MSAL.NET te gebruiken met Microsoft. Identity.Web.
Belangrijke verschillen begrijpen
| Aspect | ADAL.NET (afgeschaft) | MSAL.NET + Microsoft. Identity.Web |
|---|---|---|
| Scopes | Bronnengebaseerd (https://graph.microsoft.com) |
Op bereik gebaseerd (https://graph.microsoft.com/.default) |
| Tokencache | Handmatige serialisatie vereist | Ingebouwde adapters via extensiemethoden |
| Certificates | Handmatig X509Certificate2 laden |
DefaultCertificateLoader met meerdere bronnen |
| Autoriteit | Vast bij de bouw | Kan per aanvraag worden overschreven |
Migratievoorbeelden vergelijken
ADAL.NET (oud):
AuthenticationContext authContext = new AuthenticationContext(authority);
ClientCredential credential = new ClientCredential(clientId, clientSecret);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, credential);
MSAL.NET met Microsoft. Identity.Web (nieuw):
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();
Verwante inhoud verkennen
Gebruik deze resources voor meer informatie over gerelateerde scenario's.