Microsoft Graph API
💡 Vad är Microsoft Graph?
Microsoft Graph är som nyckeln till hela Microsoft-universumet!
Tänk dig Microsoft Graph som en universalfernkontroll för allt Microsoft - Outlook, Teams, OneDrive, Azure AD, Office 365. Istället för att komma ihåg hundra olika API:er kan du använda EN Graph-query för att hämta allt.
🎯 TL;DR
Microsoft Graph = EN API för alla Microsoft-tjänster. Hämta emails, kalendrar, filer, användare, Teams-meddelanden - allt via samma endpoint med OAuth2-autentisering.
📋 Efter att ha läst detta kommer du att kunna
- Förstå vad Microsoft Graph är och vad du kan göra med det
- Registrera en app i Azure AD för Graph-åtkomst
- Implementera OAuth2-autentisering för Graph
- Hämta data från olika Microsoft-tjänster
- Skapa och uppdatera data via Graph
🔧 Grundprinciper
Princip 1: En endpoint för allt
https://graph.microsoft.com/v1.0/ + vad du vill ha
Princip 2: OAuth2-säkerhet
Alla anrop kräver access tokens från Azure AD.
Princip 3: RESTful men enhetligt
Samma mönster för alla Microsoft-tjänster.
💭 Vad kan du hämta?
💬 Microsoft Graph ger dig åtkomst till:
ANVÄNDARE & GRUPPER:
/me - Din profil
/users - Alla användare
/groups - Alla grupper
OUTLOOK & EMAIL:
/me/messages - Dina emails
/me/calendar/events - Din kalender
/me/contacts - Dina kontakter
ONEDRIVE & FILER:
/me/drive/root/children - Dina filer
/sites - SharePoint-sajter
TEAMS & SAMARBETE:
/me/chats - Teams-chattar
/teams - Teams du är med i
/me/presence - Din status (online/offline)
OFFICE DOKUMENT:
/me/drive/items/{id}/workbook - Excel-filer
🚀 Microsoft Graph i praktiken
🟢 Registrera app i Azure AD
1. Gå till https://portal.azure.com
2. Azure Active Directory → App registrations → New registration
3. Ge appen ett namn: "Min Graph App"
4. Supported account types: "Accounts in this organizational directory only"
5. Redirect URI: Web → https://localhost:5001/signin-oidc
6. Register
7. Anteckna:
- Application (client) ID
- Directory (tenant) ID
8. Certificates & secrets → New client secret
- Anteckna Secret Value (visas bara en gång!)
9. API permissions → Add a permission → Microsoft Graph
- Lägg till nödvändiga permissions (t.ex. User.Read, Mail.Read)
🟡 Grundläggande Graph-klient i C-Sharp
// Install: dotnet add package Microsoft.Graph
// dotnet add package Microsoft.Graph.Auth
using Microsoft.Graph;
using Microsoft.Graph.Auth;
using Microsoft.Identity.Client;
public class GraphService
{
private readonly GraphServiceClient _graphServiceClient;
public GraphService(IConfiguration configuration)
{
// Konfiguration från appsettings.json
var clientId = configuration["AzureAd:ClientId"];
var clientSecret = configuration["AzureAd:ClientSecret"];
var tenantId = configuration["AzureAd:TenantId"];
// Skapa MSAL-klient för autentisering
var confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithClientSecret(clientSecret)
.WithAuthority(new Uri($"https://login.microsoftonline.com/{tenantId}"))
.Build();
// Skapa Graph-klient
var authProvider = new ClientCredentialProvider(confidentialClientApplication);
_graphServiceClient = new GraphServiceClient(authProvider);
}
// Hämta alla användare
public async Task<List<User>> GetUsersAsync()
{
var users = await _graphServiceClient.Users
.Request()
.Select("id,displayName,mail,userPrincipalName")
.GetAsync();
return users.ToList();
}
// Hämta specifik användare
public async Task<User> GetUserAsync(string userId)
{
return await _graphServiceClient.Users[userId]
.Request()
.GetAsync();
}
// Hämta användarens emails
public async Task<List<Message>> GetUserEmailsAsync(string userId)
{
var messages = await _graphServiceClient.Users[userId].Messages
.Request()
.Select("subject,from,receivedDateTime,bodyPreview")
.Top(10)
.OrderBy("receivedDateTime desc")
.GetAsync();
return messages.ToList();
}
}
appsettings.json:
{
"AzureAd": {
"ClientId": "din-client-id-från-azure",
"ClientSecret": "din-client-secret-från-azure",
"TenantId": "din-tenant-id-från-azure"
}
}
🔴 Avancerat: Web-app med användarinloggning
// Program.cs för web-app med Microsoft Graph
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
var builder = WebApplication.CreateBuilder(args);
// Lägg till Microsoft Identity Web
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
.AddInMemoryTokenCaches();
// Kräv autentisering för alla controllers
builder.Services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
builder.Services.AddRazorPages().AddMicrosoftIdentityUI();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();
app.Run();
// Controller som använder Graph
[Authorize]
public class HomeController : Controller
{
private readonly GraphServiceClient _graphServiceClient;
public HomeController(GraphServiceClient graphServiceClient)
{
_graphServiceClient = graphServiceClient;
}
public async Task<IActionResult> Index()
{
// Hämta inloggad användares profil
var user = await _graphServiceClient.Me
.Request()
.GetAsync();
ViewBag.UserName = user.DisplayName;
ViewBag.UserEmail = user.Mail;
return View();
}
public async Task<IActionResult> Emails()
{
// Hämta användarens emails
var messages = await _graphServiceClient.Me.Messages
.Request()
.Select("subject,from,receivedDateTime,bodyPreview")
.Top(20)
.OrderBy("receivedDateTime desc")
.GetAsync();
return View(messages);
}
public async Task<IActionResult> Calendar()
{
// Hämta kommande kalenderhändelser
var events = await _graphServiceClient.Me.Calendar.Events
.Request()
.Filter($"start/dateTime ge '{DateTime.Now:yyyy-MM-ddTHH:mm:ss}'")
.OrderBy("start/dateTime")
.Top(10)
.GetAsync();
return View(events);
}
}
📧 Specifika Graph-operationer
Skicka email
public async Task SendEmailAsync(string recipientEmail, string subject, string body)
{
var message = new Message
{
Subject = subject,
Body = new ItemBody
{
ContentType = BodyType.Html,
Content = body
},
ToRecipients = new List<Recipient>
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = recipientEmail
}
}
}
};
await _graphServiceClient.Me.SendMail(message)
.Request()
.PostAsync();
}
Skapa kalenderhändelse
public async Task<Event> CreateCalendarEventAsync(string subject, DateTime startTime, DateTime endTime)
{
var newEvent = new Event
{
Subject = subject,
Start = new DateTimeTimeZone
{
DateTime = startTime.ToString("yyyy-MM-ddTHH:mm:ss"),
TimeZone = "Europe/Stockholm"
},
End = new DateTimeTimeZone
{
DateTime = endTime.ToString("yyyy-MM-ddTHH:mm:ss"),
TimeZone = "Europe/Stockholm"
}
};
return await _graphServiceClient.Me.Calendar.Events
.Request()
.AddAsync(newEvent);
}
Ladda upp fil till OneDrive
public async Task<DriveItem> UploadFileAsync(string fileName, Stream fileStream)
{
return await _graphServiceClient.Me.Drive.Root
.ItemWithPath(fileName)
.Content
.Request()
.PutAsync<DriveItem>(fileStream);
}
🔐 Permissions och säkerhet
Application Permissions vs Delegated Permissions
DELEGATED PERMISSIONS (för web-appar med inloggade användare):
- User.Read - Läs användarens profil
- Mail.Read - Läs användarens mail
- Calendar.ReadWrite - Läs/skriv kalendern
- Files.ReadWrite - Läs/skriv filer
APPLICATION PERMISSIONS (för daemon/service-appar):
- User.Read.All - Läs alla användares profiler
- Mail.Read.All - Läs alla användares mail
- Calendar.ReadWrite.All - Läs/skriv alla kalendrar
VIKTIGT: Application permissions kräver admin-godkännande!
⚠️ Vanliga misstag
Misstag 1: Glömma registrera rätt permissions
- Graph returnerar 403 Forbidden
- Lösning: Lägg till permission i Azure AD och be admin att godkänna
Misstag 2: Använda fel token-typ
- Application permissions behöver client credentials flow
- User permissions behöver authorization code flow
Misstag 3: Inte hantera rate limiting
- Graph har gränser för hur många anrop du kan göra
- Lösning: Implementera retry-logic med exponential backoff
// Retry-logic för Graph API
public async Task<T> ExecuteWithRetryAsync<T>(Func<Task<T>> graphCall)
{
int maxRetries = 3;
int delay = 1000; // ms
for (int i = 0; i < maxRetries; i++)
{
try
{
return await graphCall();
}
catch (ServiceException ex) when (ex.Error.Code == "TooManyRequests")
{
if (i == maxRetries - 1) throw;
// Vänta längre för varje retry
await Task.Delay(delay * (int)Math.Pow(2, i));
}
}
throw new Exception("Max retries exceeded");
}
🧪 Testing med Graph Explorer
Graph Explorer (https://developer.microsoft.com/en-us/graph/graph-explorer) låter dig testa Graph-queries direkt:
GET https://graph.microsoft.com/v1.0/me
GET https://graph.microsoft.com/v1.0/me/messages?$top=5
GET https://graph.microsoft.com/v1.0/me/calendar/events?$filter=start/dateTime ge '2024-01-01T00:00:00'
📚 Sammanfattning
Microsoft Graph är kraftfullt för Microsoft-integrationer:
- En API för hela Microsoft-ekosystemet
- OAuth2-säkerhet via Azure AD
- RESTful med konsekvent struktur
- Rika permissions för olika scenarion
- Bra dokumentation och verktyg
🎯 Övningar
- 🟢 Grundläggande: Registrera en app och hämta din profil via Graph
- 🟡 Utmanande: Bygg en enkel mail-reader som visar dina emails
- 🔴 Expert: Skapa en Teams-bot som kan skicka meddelanden via Graph
😄 Obligatorisk dad joke
Varför är Microsoft Graph så populär på kontoret? För att det är det enda som kan grafera alla relationer mellan kollegorna! 📊