Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Rufen Sie Microsoft Graph aus Ihren ASP.NET Core- und OWIN-Anwendungen mithilfe von Microsoft.Identity.Web und dem Microsoft Graph SDK auf, um auf Daten und Dienste von Microsoft 365 zuzugreifen.
Grundlegendes zur Microsoft Graph Integration
Microsoft Graph bietet einen einheitlichen API-Endpunkt für den Zugriff auf Daten über Microsoft 365, Windows und Enterprise Mobility + Security hinweg. Microsoft. Identity.Web vereinfacht die Authentifizierung und den Tokenerwerb für Microsoft Graph, während das Microsoft Graph SDK eine fluent-typierte API zum Aufrufen von Graph-Endpunkten bereitstellt.
Wählen Sie Microsoft.Identity.Web.GraphServiceClient
Die folgenden Vorteile machen Microsoft.Identity.Web.GraphServiceClient zum empfohlenen Ansatz für den Aufruf des Microsoft Graph.
- Automatische Tokenerfassung: Verarbeitet Benutzer- und App-Token nahtlos
- Tokenzwischenspeicherung: Integriertes Zwischenspeichern für die Leistung
- Fluent-API: Typensichere, IntelliSense-freundliche Graph-Aufrufe
- Inkrementelle Zustimmung: Anfordern zusätzlicher Bereiche bei Bedarf
- Mehrere Authentifizierungsschemas: Unterstützung für Web-Apps und Web-APIs
- Sowohl v1.0 als auch Beta: Stabile und Vorschau-Endpunkte gemeinsam verwenden
Installieren Sie die erforderlichen Pakete
Installieren Sie das Microsoft Graph SDK-Integrationspaket:
dotnet add package Microsoft.Identity.Web.GraphServiceClient
Für Microsoft Graph Beta-APIs:
dotnet add package Microsoft.Identity.Web.GraphServiceClientBeta
Einrichten von ASP.NET Core
1. Konfigurieren von Diensten
Fügen Sie Ihrer Anwendung Microsoft Graph Unterstützung hinzu:
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
// Add authentication (web app or web API)
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
// Add Microsoft Graph support
builder.Services.AddMicrosoftGraph();
builder.Services.AddControllersWithViews();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
2. Konfigurieren von appsettings.json
Konfigurieren von Graph-Optionen in Ihrer Konfigurationsdatei:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret",
"CallbackPath": "/signin-oidc"
},
"DownstreamApis": {
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": ["User.Read", "User.ReadBasic.All"]
}
}
}
Konfiguration mit Code:
builder.Services.AddMicrosoftGraph(options =>
{
builder.Configuration.GetSection("DownstreamApis:MicrosoftGraph").Bind(options);
});
Oder konfigurieren Sie direkt im Code:
builder.Services.AddMicrosoftGraph();
builder.Services.Configure<MicrosoftGraphOptions>(options =>
{
options.BaseUrl = "https://graph.microsoft.com/v1.0";
options.Scopes = new[] { "User.Read", "Mail.Read" };
});
3. Konfigurieren der nationalen Cloudunterstützung
Um Microsoft Graph in nationalen Clouds zu verwenden, geben Sie die BaseUrl in Ihrer Konfiguration an:
{
"DownstreamApis": {
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.us/v1.0",
"Scopes": ["User.Read"]
}
}
}
Informationen zu Endpunkt-URLs finden Sie unter Microsoft Graph deployments.
Verwenden von GraphServiceClient
Einfügen von GraphServiceClient
Einfügen GraphServiceClient aus dem Konstruktor:
using Microsoft.Graph;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[Authorize]
public class ProfileController : Controller
{
private readonly GraphServiceClient _graphClient;
public ProfileController(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
public async Task<IActionResult> Index()
{
// Call Microsoft Graph
var user = await _graphClient.Me.GetAsync();
return View(user);
}
}
Verwenden delegierter Berechtigungen (Benutzertoken)
Rufen Sie Graph im Namen des angemeldeten Benutzers mit delegierten Berechtigungen auf.
Abrufen eines einfachen Benutzerprofils
Rufen Sie die Profilinformationen des aktuellen Benutzers aus Microsoft Graph ab.
[Authorize]
public class ProfileController : Controller
{
private readonly GraphServiceClient _graphClient;
public ProfileController(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
public async Task<IActionResult> Me()
{
// Get current user's profile
var user = await _graphClient.Me.GetAsync();
return View(new UserViewModel
{
DisplayName = user.DisplayName,
Mail = user.Mail,
JobTitle = user.JobTitle
});
}
}
Inkrementelle Zustimmung anfordern
Fordern Sie zusätzliche Bereiche dynamisch an, wenn Ihre Anwendung sie benötigt:
[Authorize]
[AuthorizeForScopes("Mail.Read")]
public class MailController : Controller
{
private readonly GraphServiceClient _graphClient;
public MailController(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
public async Task<IActionResult> Inbox()
{
try
{
// Request Mail.Read scope dynamically
var messages = await _graphClient.Me.Messages
.GetAsync(r => r.Options.WithScopes("Mail.Read"));
return View(messages);
}
catch (MicrosoftIdentityWebChallengeUserException)
{
// ASP.NET Core will redirect user to consent
// thansk to the AuthorizeForScopes attribute.
throw;
}
}
}
Anwenden von Abfrageoptionen
Verwenden Von Graph SDK-Abfrageoptionen zum Filtern, Auswählen und Sortieren von Ergebnissen:
public async Task<IActionResult> UnreadMessages()
{
var messages = await _graphClient.Me.Messages
.GetAsync(requestConfiguration =>
{
requestConfiguration.QueryParameters.Filter = "isRead eq false";
requestConfiguration.QueryParameters.Select = new[] { "subject", "from", "receivedDateTime" };
requestConfiguration.QueryParameters.Orderby = new[] { "receivedDateTime desc" };
requestConfiguration.QueryParameters.Top = 10;
// Request specific scope
requestConfiguration.Options.WithScopes("Mail.Read");
});
return View(messages);
}
Ergebnisse durchblättern
Behandeln Sie seitenseitige Ergebnisse aus Microsoft Graph, indem Sie die einzelnen Seiten durchlaufen:
public async Task<IActionResult> AllUsers()
{
var allUsers = new List<User>();
// Get first page
var users = await _graphClient.Users
.GetAsync(r => r.Options.WithScopes("User.ReadBasic.All"));
// Add first page
allUsers.AddRange(users.Value);
// Iterate through remaining pages
var pageIterator = PageIterator<User, UserCollectionResponse>
.CreatePageIterator(
_graphClient,
users,
user =>
{
allUsers.Add(user);
return true; // Continue iteration
});
await pageIterator.IterateAsync();
return View(allUsers);
}
Verwenden von Anwendungsberechtigungen (nur App-Token)
Aufrufen von Graph mit Anwendungsberechtigungen, wenn kein Benutzerkontext erforderlich ist.
Aufrufen von Graph mit WithAppOnly()
Verwenden Sie die WithAppOnly() Methode, um Graph-Aufrufe mit Anwendungsberechtigungen auszuführen.
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class AdminController : ControllerBase
{
private readonly GraphServiceClient _graphClient;
public AdminController(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
[HttpGet("users/count")]
public async Task<ActionResult<int>> GetUserCount()
{
// Get count using app permissions
var count = await _graphClient.Users.Count
.GetAsync(r => r.Options.WithAppOnly());
return Ok(count);
}
[HttpGet("applications")]
public async Task<ActionResult> GetApplications()
{
// List applications using app permissions
var apps = await _graphClient.Applications
.GetAsync(r => r.Options.WithAppOnly());
return Ok(apps.Value);
}
}
Konfigurieren von App-Berechtigungen
Geben Sie eine App-Token-Anforderung in appsettings.json an:
{
"DownstreamApis": {
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"RequestAppToken": true
}
}
}
Die Gültigkeitsbereiche werden automatisch auf ["https://graph.microsoft.com/.default"] gesetzt.
Konfigurieren detaillierter Nur-App-Optionen
Legen Sie explizite Nur-App-Authentifizierungsoptionen im Code fest.
public async Task<IActionResult> GetApplicationsDetailed()
{
var apps = await _graphClient.Applications
.GetAsync(r =>
{
r.Options.WithAuthenticationOptions(options =>
{
// Request app token explicitly
options.RequestAppToken = true;
// Scopes automatically become [.default]
// No need to specify: options.Scopes = new[] { "https://graph.microsoft.com/.default" };
});
});
return Ok(apps);
}
Behandeln mehrerer Authentifizierungsschemas
Wenn Ihre App mehrere Authentifizierungsschemas verwendet (z. B. Web App + API), geben Sie an, welches Schema verwendet werden soll:
using Microsoft.AspNetCore.Authentication.JwtBearer;
[Authorize]
public class ApiDataController : ControllerBase
{
private readonly GraphServiceClient _graphClient;
public ApiDataController(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
[HttpGet("profile")]
public async Task<ActionResult> GetProfile()
{
// Specify JWT Bearer scheme
var user = await _graphClient.Me
.GetAsync(r => r.Options
.WithAuthenticationScheme(JwtBearerDefaults.AuthenticationScheme));
return Ok(user);
}
}
Konfigurieren detaillierter Schemaoptionen
Legen Sie das Authentifizierungsschema und die Bereiche explizit im Code fest.
public async Task<ActionResult> GetMailWithScheme()
{
var messages = await _graphClient.Me.Messages
.GetAsync(r =>
{
r.Options.WithAuthenticationOptions(options =>
{
// Specify authentication scheme
options.AcquireTokenOptions.AuthenticationOptionsName =
JwtBearerDefaults.AuthenticationScheme;
// Specify scopes
options.Scopes = new[] { "Mail.Read" };
});
});
return Ok(messages);
}
Verwenden von v1.0- und Beta-Endpunkten
Registrieren und Aufrufen von Microsoft Graph v1.0 und Beta in derselben Anwendung.
1. Installieren sie beide Pakete.
dotnet add package Microsoft.Identity.Web.GraphServiceClient
dotnet add package Microsoft.Identity.Web.GraphServiceClientBeta
2. Registrieren beider Dienste
using Microsoft.Identity.Web;
builder.Services.AddMicrosoftGraph();
builder.Services.AddMicrosoftGraphBeta();
3. Verwenden Sie beide Clients.
using GraphServiceClient = Microsoft.Graph.GraphServiceClient;
using GraphBetaServiceClient = Microsoft.Graph.Beta.GraphServiceClient;
public class MyController : Controller
{
private readonly GraphServiceClient _graphClient;
private readonly GraphBetaServiceClient _graphBetaClient;
public MyController(
GraphServiceClient graphClient,
GraphBetaServiceClient graphBetaClient)
{
_graphClient = graphClient;
_graphBetaClient = graphBetaClient;
}
public async Task<IActionResult> GetData()
{
// Use stable v1.0 endpoint
var user = await _graphClient.Me.GetAsync();
// Use beta endpoint for preview features
var profile = await _graphBetaClient.Me.Profile.GetAsync();
return View(new { user, profile });
}
}
Batchanforderungen senden
Kombinieren Sie mehrere Graph-Aufrufe in einer einzelnen HTTP-Anforderung, um die Leistung zu verbessern:
using Microsoft.Graph.Models;
public async Task<IActionResult> GetDashboard()
{
var batchRequestContent = new BatchRequestContentCollection(_graphClient);
// Add multiple requests to batch
var userRequest = _graphClient.Me.ToGetRequestInformation();
var messagesRequest = _graphClient.Me.Messages.ToGetRequestInformation();
var eventsRequest = _graphClient.Me.Events.ToGetRequestInformation();
var userRequestId = await batchRequestContent.AddBatchRequestStepAsync(userRequest);
var messagesRequestId = await batchRequestContent.AddBatchRequestStepAsync(messagesRequest);
var eventsRequestId = await batchRequestContent.AddBatchRequestStepAsync(eventsRequest);
// Send batch request
var batchResponse = await _graphClient.Batch.PostAsync(batchRequestContent);
// Extract responses
var user = await batchResponse.GetResponseByIdAsync<User>(userRequestId);
var messages = await batchResponse.GetResponseByIdAsync<MessageCollectionResponse>(messagesRequestId);
var events = await batchResponse.GetResponseByIdAsync<EventCollectionResponse>(eventsRequestId);
return View(new DashboardViewModel
{
User = user,
Messages = messages.Value,
Events = events.Value
});
}
Anwenden allgemeiner Graph-Muster
Verwenden Sie diese Muster, um häufige Microsoft Graph Vorgänge in Ihrer Anwendung auszuführen.
Manager des Benutzers abrufen
Rufen Sie den Vorgesetzten des angemeldeten Benutzers aus dem Verzeichnis ab.
public async Task<IActionResult> GetManager()
{
var manager = await _graphClient.Me.Manager.GetAsync();
// Cast to User (manager is DirectoryObject)
if (manager is User managerUser)
{
return View(managerUser);
}
return NotFound("Manager not found");
}
Benutzerfoto abrufen
Laden Sie das Profilfoto des angemeldeten Benutzers als Datenstrom herunter.
public async Task<IActionResult> GetPhoto()
{
try
{
var photoStream = await _graphClient.Me.Photo.Content.GetAsync();
return File(photoStream, "image/jpeg");
}
catch (ServiceException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return NotFound("Photo not available");
}
}
E-Mail senden
Senden Sie eine E-Mail-Nachricht im Namen des angemeldeten Benutzers.
public async Task<IActionResult> SendEmail([FromBody] EmailRequest request)
{
var message = new Message
{
Subject = request.Subject,
Body = new ItemBody
{
ContentType = BodyType.Html,
Content = request.Body
},
ToRecipients = new List<Recipient>
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = request.ToEmail
}
}
}
};
await _graphClient.Me.SendMail
.PostAsync(new SendMailPostRequestBody
{
Message = message,
SaveToSentItems = true
},
requestConfiguration =>
{
requestConfiguration.Options.WithScopes("Mail.Send");
});
return Ok("Email sent");
}
Kalenderereignis erstellen
Erstellen Sie ein neues Kalenderereignis mit Teilnehmern für den angemeldeten Benutzer.
public async Task<IActionResult> CreateEvent([FromBody] EventRequest request)
{
var newEvent = new Event
{
Subject = request.Subject,
Start = new DateTimeTimeZone
{
DateTime = request.StartTime.ToString("yyyy-MM-ddTHH:mm:ss"),
TimeZone = "UTC"
},
End = new DateTimeTimeZone
{
DateTime = request.EndTime.ToString("yyyy-MM-ddTHH:mm:ss"),
TimeZone = "UTC"
},
Attendees = request.Attendees.Select(email => new Attendee
{
EmailAddress = new EmailAddress { Address = email },
Type = AttendeeType.Required
}).ToList()
};
var createdEvent = await _graphClient.Me.Events
.PostAsync(newEvent, r => r.Options.WithScopes("Calendars.ReadWrite"));
return Ok(createdEvent);
}
Benutzer durchsuchen
Suchen Sie nach Benutzern im Verzeichnis anhand des Anzeigenamens oder der E-Mail-Adresse.
public async Task<IActionResult> SearchUsers(string searchTerm)
{
var users = await _graphClient.Users
.GetAsync(requestConfiguration =>
{
requestConfiguration.QueryParameters.Filter =
$"startswith(displayName,'{searchTerm}') or startswith(mail,'{searchTerm}')";
requestConfiguration.QueryParameters.Select =
new[] { "displayName", "mail", "jobTitle" };
requestConfiguration.QueryParameters.Top = 10;
requestConfiguration.Options.WithScopes("User.ReadBasic.All");
});
return Ok(users.Value);
}
Implementieren der OWIN-Unterstützung
Konfigurieren Sie für ASP.NET Anwendungen, die OWIN verwenden, die Token-Acquirer-Factory, und registrieren Sie Microsoft Graph Dienste.
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.OWIN;
using Owin;
public class Startup
{
public void Configuration(IAppBuilder app)
{
OwinTokenAcquirerFactory factory = TokenAcquirerFactory.GetDefaultInstance<OwinTokenAcquirerFactory>();
app.AddMicrosoftIdentityWebApi(factory);
factory.Services
.AddMicrosoftGraph();
factory.Build();
}
}
2. Aufrufen der API von Controllern
Rufen Sie eine GraphServiceClient-Instanz in Ihrem Controller ab, und rufen Sie Microsoft Graph auf.
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;
using System.Web.Http;
[Authorize]
public class DataController : ApiController
{
public DataController()
{
}
public async Task<IHttpActionResult> GetMyProfile()
{
GraphServiceClient graphServiceClient = this.GetGraphServiceClient();
var me = await graphServiceClient.Me.GetAsync();
return Ok(me);
}
}
Migrieren sie von Microsoft. Identity.Web.MicrosoftGraph 2.x
Wenn Sie vom älteren Microsoft.Identity.Web.MicrosoftGraph-Paket (SDK 4.x) migrieren, überarbeiten Sie die folgenden wesentlichen Änderungen:
1. Entfernen Des alten Pakets und Hinzufügen eines neuen Pakets
dotnet remove package Microsoft.Identity.Web.MicrosoftGraph
dotnet add package Microsoft.Identity.Web.GraphServiceClient
2. Aktualisieren der Methodenaufrufe
Die .Request() Methode wurde in SDK 5.x entfernt:
Before (SDK 4.x):
var user = await _graphClient.Me.Request().GetAsync();
var messages = await _graphClient.Me.Messages
.Request()
.WithScopes("Mail.Read")
.GetAsync();
After (SDK 5.x):
var user = await _graphClient.Me.GetAsync();
var messages = await _graphClient.Me.Messages
.GetAsync(r => r.Options.WithScopes("Mail.Read"));
3. Aktualisieren von WithScopes()-Speicherort
Before:
var users = await _graphClient.Users
.Request()
.WithScopes("User.Read.All")
.GetAsync();
After:
var users = await _graphClient.Users
.GetAsync(r => r.Options.WithScopes("User.Read.All"));
4. Aktualisieren von WithAppOnly()-Speicherort
Before:
var apps = await _graphClient.Applications
.Request()
.WithAppOnly()
.GetAsync();
After:
var apps = await _graphClient.Applications
.GetAsync(r => r.Options.WithAppOnly());
5. Aktualisieren Sie die WithAuthenticationScheme()-Ort
Before:
var user = await _graphClient.Me
.Request()
.WithAuthenticationScheme(JwtBearerDefaults.AuthenticationScheme)
.GetAsync();
After:
var user = await _graphClient.Me
.GetAsync(r => r.Options
.WithAuthenticationScheme(JwtBearerDefaults.AuthenticationScheme));
Vollständige Migrationsdetails finden Sie unter Microsoft Graph .NET SDK v5 changelog.
Fehler behandeln
Umgang mit ServiceException
Fangen Sie ODataError und MicrosoftIdentityWebChallengeUserException ab, um Graph-API-Fehler elegant zu beheben.
using Microsoft.Graph.Models.ODataErrors;
public async Task<IActionResult> GetData()
{
try
{
var user = await _graphClient.Me.GetAsync();
return Ok(user);
}
catch (ODataError ex) when (ex.ResponseStatusCode == 404)
{
return NotFound("Resource not found");
}
catch (ODataError ex) when (ex.ResponseStatusCode == 403)
{
return Forbid("Insufficient permissions");
}
catch (MicrosoftIdentityWebChallengeUserException)
{
// User needs to consent
throw;
}
catch (Exception ex)
{
_logger.LogError(ex, "Graph API call failed");
return StatusCode(500, "An error occurred");
}
}
Bewährte Methoden befolgen
1. Mindestbereiche anfordern
Nur Anforderungsbereiche, die Sie benötigen:
// Bad: Requesting too many scopes
options.Scopes = new[] { "User.Read", "Mail.ReadWrite", "Calendars.ReadWrite", "Files.ReadWrite.All" };
// Good: Request only what you need
options.Scopes = new[] { "User.Read" };
2. Inkrementelle Zustimmung verwenden
Fordern Sie nur bei Bedarf zusätzliche Bereiche an:
// Sign-in: Only User.Read
// Later, when accessing mail:
var messages = await _graphClient.Me.Messages
.GetAsync(r => r.Options.WithScopes("Mail.Read"));
3. Cache für GraphServiceClient
GraphServiceClient ist sicher, um wiederverwendet zu werden. Registrieren Sie sich als Singleton oder injizieren Sie aus DI.
4. Verwenden Sie "Select", um die Antwortgröße zu verringern.
// Bad: Getting all properties
var users = await _graphClient.Users.GetAsync();
// Good: Select only needed properties
var users = await _graphClient.Users
.GetAsync(r => r.QueryParameters.Select =
new[] { "displayName", "mail", "id" });
Häufige Probleme beheben
Auflösen von "Unzureichende Berechtigungen zum Abschließen des Vorgangs"
Ursache: Die App verfügt nicht über erforderliche Graph-Berechtigungen.
Lösung:
- Hinzufügen erforderlicher API-Berechtigungen in der App-Registrierung
- Administratorzustimmung für App-Berechtigungen erforderlich
- Für delegierte Berechtigungen erforderliche Benutzergenehmigung
Auflösen von "AADSTS65001: Der Benutzer oder Administrator hat nicht zugestimmt"
Ursache: Der Benutzer hat den angeforderten Bereichen nicht zugestimmt.
Lösung: Verwenden Sie inkrementelles Einverständnis mit .WithScopes(), um den Zustimmungsfluss auszulösen.
Beheben von Foto 404-Fehlern
Ursache: Der Benutzer hat kein Profilfoto.
Lösung: Behandeln Sie 404 ordnungsgemäß und stellen Sie standardmäßigen Avatar bereit.
Beheben von Batchanforderungsfehlern
Ursache: Einzelne Anforderungen im Batch können unabhängig voneinander fehlschlagen.
Lösung: Überprüfen Sie jede Antwort im Batch auf Fehler:
var userResponse = await batchResponse.GetResponseByIdAsync<User>(userRequestId);
if (userResponse == null)
{
// Handle individual request failure
}
Verwandte Inhalte
- Microsoft Graph Dokumentation
- Graph SDK v5-Migrationshandbuch
- Übersicht über aufrufende Downstream-APIs
- Anrufen von Web-Apps
- Aufrufen von Web-APIs
Nächste Schritte: Erfahren Sie mehr über Calling Azure SDKs oder custom APIs.