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.
Roep Microsoft Graph aan vanuit uw ASP.NET Core- en OWIN-toepassingen met behulp van Microsoft. Identity.Web en de Microsoft Graph SDK voor toegang tot Microsoft 365 gegevens en services.
Inzicht in Microsoft Graph-integratie
Microsoft Graph biedt een geïntegreerd API-eindpunt voor toegang tot gegevens in Microsoft 365, Windows en Enterprise Mobility + Security. Microsoft. Identity.Web vereenvoudigt verificatie en tokenverwerving voor Microsoft Graph, terwijl de Microsoft Graph SDK een vloeiende, getypte API biedt voor het aanroepen van Graph-eindpunten.
Kies Microsoft. Identity.Web.GraphServiceClient
De volgende voordelen maken Microsoft.Identity.Web.GraphServiceClient de aanbevolen methode voor het aanroepen van Microsoft Graph.
- Automatische tokenverwerving: verwerkt naadloos gebruikers- en app-tokens
- Tokencaching: ingebouwde caching voor prestaties
- Fluent API: Type-safe en IntelliSense-vriendelijke Graph-aanroepen
- Incrementele toestemming: aanvullende rechten op aanvraag vragen
- Meerdere verificatieschema's: ondersteuning voor web-apps en web-API's
- Zowel v1.0 als bèta: stabiele en preview-eindpunten samen gebruiken
De vereiste pakketten installeren
Installeer het Microsoft Graph SDK-integratiepakket:
dotnet add package Microsoft.Identity.Web.GraphServiceClient
Voor Microsoft Graph bèta-API's:
dotnet add package Microsoft.Identity.Web.GraphServiceClientBeta
ASP.NET Core instellen
1. Services configureren
Voeg Microsoft Graph ondersteuning toe aan uw toepassing:
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. Configureer appsettings.json
De configopties voor grafieken instellen in uw configuratiebestand:
{
"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"]
}
}
}
Configuratie met code:
builder.Services.AddMicrosoftGraph(options =>
{
builder.Configuration.GetSection("DownstreamApis:MicrosoftGraph").Bind(options);
});
Of configureer rechtstreeks in 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. Nationale cloudondersteuning configureren
Als u Microsoft Graph in nationale clouds wilt gebruiken, geeft u de BaseUrl op in uw configuratie:
{
"DownstreamApis": {
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.us/v1.0",
"Scopes": ["User.Read"]
}
}
}
Zie Microsoft Graph-implementaties voor eindpunt-URL's.
GraphServiceClient gebruiken
GraphServiceClient injecteren
Injecteren GraphServiceClient vanuit de constructor:
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);
}
}
Gedelegeerde machtigingen gebruiken (gebruikerstokens)
Roep Graph aan namens de aangemelde gebruiker met gedelegeerde machtigingen.
Basisgebruikersprofiel ophalen
Haal de profielgegevens van de huidige gebruiker op uit Microsoft Graph.
[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
});
}
}
Incrementele toestemming aanvragen
Vraag dynamisch aanvullende bereiken aan wanneer uw toepassing deze nodig heeft:
[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;
}
}
}
Queryopties toepassen
Gebruik Graph SDK-queryopties om resultaten te filteren, te selecteren en te ordenen:
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);
}
Bladeren door resultaten
Behandel paginaresultaten van Microsoft Graph door elke pagina door te nemen:
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);
}
Toepassingsmachtigingen gebruiken (alleen-app-tokens)
Roep Graph aan met toepassingsmachtigingen wanneer er geen gebruikerscontext is vereist.
Grafiek aanroepen met WithAppOnly()
Gebruik de WithAppOnly() methode om Graph-aanroepen te maken met toepassingsmachtigingen.
[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);
}
}
App-machtigingen configureren
Geef een app-tokenaanvraag op in appsettings.json:
{
"DownstreamApis": {
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"RequestAppToken": true
}
}
}
De scopes worden automatisch ingesteld op ["https://graph.microsoft.com/.default"].
Gedetailleerde opties alleen voor apps configureren
Stel expliciete opties voor app-only authenticatie in binnen de code.
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);
}
Meerdere verificatieschema's hanteren
Als uw app gebruikmaakt van meerdere verificatieschema's (bijvoorbeeld web-app + API), geeft u op welk schema u wilt gebruiken:
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);
}
}
Gedetailleerde schemaopties configureren
Stel het verificatieschema en de scopes expliciet in de code in.
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);
}
Zowel v1.0- als bèta-eindpunten gebruiken
Registreer en roep zowel Microsoft Graph v1.0 als beta aan in dezelfde toepassing.
1. Beide pakketten installeren
dotnet add package Microsoft.Identity.Web.GraphServiceClient
dotnet add package Microsoft.Identity.Web.GraphServiceClientBeta
2. Beide services registreren
using Microsoft.Identity.Web;
builder.Services.AddMicrosoftGraph();
builder.Services.AddMicrosoftGraphBeta();
3. Beide clients gebruiken
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 });
}
}
Batchaanvragen verzenden
Combineer meerdere Graph-aanroepen in één HTTP-aanvraag om de prestaties te verbeteren:
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
});
}
Algemene grafiekpatronen toepassen
Gebruik deze patronen om frequente Microsoft Graph bewerkingen uit te voeren in uw toepassing.
Het verkrijgen van de manager van de gebruiker
Haal de manager van de aangemelde gebruiker op uit de directory.
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");
}
Foto van gebruiker ophalen
Download de profielfoto van de aangemelde gebruiker als een stream.
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 verzenden
Verzend een e-mailbericht namens de aangemelde gebruiker.
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");
}
Agendagebeurtenis maken
Maak een nieuwe agendagebeurtenis met deelnemers voor de aangemelde gebruiker.
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);
}
Gebruikers zoeken
Zoek naar gebruikers in het directory op weergavenaam of e-mailadres.
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);
}
OWIN-ondersteuning implementeren
Voor ASP.NET toepassingen die gebruikmaken van OWIN, configureert u de token acquirer factory en registreert u Microsoft Graph services.
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. API aanroepen vanaf controllers
Haal een GraphServiceClient-exemplaar op in uw controller en roep Microsoft Graph aan.
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);
}
}
Migreren van Microsoft. Identity.Web.MicrosoftGraph 2.x
Als u migreert van de oudere Microsoft. Identity.Web.MicrosoftGraph package (SDK 4.x), controleer de volgende belangrijke wijzigingen:
1. Oud pakket verwijderen en nieuw toevoegen
dotnet remove package Microsoft.Identity.Web.MicrosoftGraph
dotnet add package Microsoft.Identity.Web.GraphServiceClient
2. Methode-aanroepen bijwerken
De .Request() methode is verwijderd in SDK 5.x:
Vóór (SDK 4.x):
var user = await _graphClient.Me.Request().GetAsync();
var messages = await _graphClient.Me.Messages
.Request()
.WithScopes("Mail.Read")
.GetAsync();
Na (SDK 5.x):
var user = await _graphClient.Me.GetAsync();
var messages = await _graphClient.Me.Messages
.GetAsync(r => r.Options.WithScopes("Mail.Read"));
Bijwerken van WithScopes() locatie
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. Bijwerken van de locatie van WithAppOnly()
Before:
var apps = await _graphClient.Applications
.Request()
.WithAppOnly()
.GetAsync();
After:
var apps = await _graphClient.Applications
.GetAsync(r => r.Options.WithAppOnly());
5. Update locatie van WithAuthenticationScheme()
Before:
var user = await _graphClient.Me
.Request()
.WithAuthenticationScheme(JwtBearerDefaults.AuthenticationScheme)
.GetAsync();
After:
var user = await _graphClient.Me
.GetAsync(r => r.Options
.WithAuthenticationScheme(JwtBearerDefaults.AuthenticationScheme));
Zie Microsoft Graph .NET SDK v5 changelog voor volledige migratiedetails.
Afhandeling van fouten
ServiceException verwerken
Catch ODataError en MicrosoftIdentityWebChallengeUserException om Graph API-fouten op een elegante manier af te handelen.
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");
}
}
Best practices volgen
1. Minimale machtigingen aanvragen
Alleen aanvraagbereiken die u nodig hebt:
// 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. Incrementele toestemming gebruiken
Vraag alleen extra bereiken aan wanneer dat nodig is:
// Sign-in: Only User.Read
// Later, when accessing mail:
var messages = await _graphClient.Me.Messages
.GetAsync(r => r.Options.WithScopes("Mail.Read"));
3. Cache GraphServiceClient
GraphServiceClient is veilig om opnieuw te gebruiken. Registreer als singleton of voer in vanuit DI.
4. Selecteer deze optie om de responsgrootte te verkleinen
// 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" });
Veelvoorkomende problemen oplossen
'Onvoldoende bevoegdheden om de bewerking te voltooien' oplossen
Oorzaak: App heeft geen vereiste Graph-machtigingen.
Solution:
- Vereiste API-machtigingen toevoegen in app-registratie
- Beheerderstoestemming vereist voor app-machtigingen
- Gebruikerstoestemming vereist voor gedelegeerde machtigingen
'AADSTS65001: de gebruiker of beheerder heeft geen toestemming gegeven' oplossen
Oorzaak: De gebruiker heeft geen toestemming gegeven voor de gevraagde machtigingen.
Oplossing: Gebruik incrementele toestemming om .WithScopes() toestemmingsstroom te activeren.
Foto 404-fouten oplossen
Oorzaak: Gebruiker heeft geen profielfoto.
Oplossing: 404 correct verwerken en standaard avatar bieden.
Fouten met batchaanvragen oplossen
Oorzaak: afzonderlijke aanvragen in batch kunnen onafhankelijk mislukken.
Oplossing: Controleer elk antwoord in batch op fouten:
var userResponse = await batchResponse.GetResponseByIdAsync<User>(userRequestId);
if (userResponse == null)
{
// Handle individual request failure
}
Verwante inhoud
- Microsoft Graph-documentatie
- Migratiehandleiding voor Graph SDK v5
- Overzicht van downstream-API's aanroepen
- Bellen vanuit Web-apps
- Aanroepen vanuit web-API's
Volgende stappen: Meer informatie over het aanroepen van Azure SDK's of aangepaste API's.