Subscribe for Microsoft Graph webhooks to be notified when your user's data changes, so you don't have to poll for changes.
This sample ASP.NET Core web application shows how to subscribe for webhooks using delegated permissions. It uses OpenID Connect for sign in / sign out using the Microsoft identity platform for developers, Microsoft Authentication Library for .NET (MSAL.NET) to obtain an access token using the auth code flow, and the Microsoft Graph Client Library for .NET (SDK) to call Microsoft Graph on behalf of a user that has successfully signed in to the web app. These complexities have been encapsulated into the Microsoft.Identity.Web
reusable library project.
See the list of delegated permissions permitted for each supported resource in Microsoft Graph.
The sample app redirects to the Azure AD adminconsent endpoint so a tenant administrator can grant delegated permissions directly to the app. After the admin consents, users in the tenant can create a subscription and watch for notifications.
The following are common tasks that an application performs with webhooks subscriptions:
- Get consent to subscribe to users' resources and then get an access token.
- Use the access token to create a subscription to a resource.
- Send back a validation token to confirm the notification URL.
- Listen for notifications from Microsoft Graph and respond with a 202 status code.
- Request more information about changed resources using data in the notification.
The screenshot below shows the app's start page.
After the app creates a subscription for the signed-in user, Microsoft Graph sends a notification to the registered endpoint when events happen in the user's subscribed resource. The app then reacts to the event.
This sample app subscribes to the users/{user-id}/mailFolders('Inbox')/messages
resource for created
changes. When notified that subscribed users receive a mail message, the app then updates a page with information about the message. The page displays only messages belonging to the signed-in user.
To use the Microsoft Graph Webhook Sample for ASP.NET Core, you need the following:
- Visual Studio 2017 installed on your development computer.
- .NET Core 2.1 or later (for example for Windows) installed. You can follow the instructions at .NET and C# - Get Started in 10 Minutes. In addition to developing on Windows, you can develop on Linux, Mac, or Docker.
- A work, school or personal account. A tenant administrator account is required to grant application permissions.
- The application ID and key from the application that you register on the Azure Portal.
- A public HTTPS endpoint to receive and send HTTP requests. You can host this on Microsoft Azure or another service, or you can use ngrok or a similar tool while testing.
- Sign in to the Azure portal using either a work or school account or a personal Microsoft account.
- If your account gives you access to more than one tenant, select your account in the top right corner, and set your portal session to the desired Azure AD tenant (using Switch Directory).
This app uses the Azure AD endpoint, so you'll register it in the Azure Portal.
-
Sign in to the portal using your work or school account.
-
Choose Azure Active Directory service in the left-hand navigation pane.
-
Choose App registrations (Preview), and then select New registration.
-
When the Register an application page appears, enter your application's registration information:
-
In the Name section, enter a meaningful application name that will be displayed to users of the app, for example
WebhookApp
. -
In the Supported account types section, select Accounts in any organizational directory and personal Microsoft accounts (e.g. Skype, Xbox, Outlook.com).
-
In the Redirect URI (optional) section, select Web in the combo-box.
-
Enter https://localhost:44334/signin-oidc for the Redirect URI. This is the base callback URL for this sample.
-
Select Register to create the application.
-
-
Choose your new application from the list of registered applications.
-
Copy and store the Application ID. This value is shown in the Essentials pane or in Settings > Properties.
-
Open Settings > Reply URLs and add the following redirect URI:
https://localhost:44334/Account/GrantPermissions
This is the callback for the adminconsent endpoint. The sample will have two redirect URIs:
-
On the app Overview page, find the Application (client) ID value and record it for later. You'll need it to configure the Visual Studio configuration file for this project.
-
In the list of pages for the app, select Authentication.
- In the Advanced settings section set Logout URL to
https://localhost:44334/signout-oidc
- In the Advanced settings | Implicit grant section, check ID tokens as this sample requires the Implicit grant flow to be enabled to sign-in the user.
- In the Advanced settings section set Logout URL to
-
Configure Permissions for your application:
-
From the Manage page, select API permissions > Add a permission.
-
Choose Microsoft API > Microsoft Graph > Delegated permissions.
-
In the search box, type Mail.Read and select the first option from the list.
Keep the User.Read delegated permission for Azure Active Directory so users can sign into the app to initiate the subscription process.
-
-
From the Certificates & secrets page, for your app registration, in the Client secrets section, choose New client secret:
-
Type a key description (of instance
app secret
),- Select a key duration of either In 1 year, In 2 years, or Never Expires.
- When you press the Add button, the key value will be displayed, copy, and save the value in a safe location.
- You'll need this key later to configure the project in Visual Studio. This key value will not be displayed again, nor retrievable by any other means.
Important: Note that in production apps you should always use certificates as your application secrets, but for this sample we will use a simple shared secret password.
You'll use the application ID and secret to configure the app in Visual Studio.
You must expose a public HTTPS endpoint to create a subscription and receive notifications from Microsoft Graph. While testing, you can use ngrok to temporarily allow messages from Microsoft Graph to tunnel to a localhost port on your computer.
You can use the ngrok web interface (http://127.0.0.1:4040) to inspect the HTTP traffic that passes through the tunnel. To learn more about using ngrok, see the ngrok website.
-
In Solution Explorer, right-click the GraphWebhooks-Core project and choose Properties.
-
On the Debug tab, copy the port number of the App URL.
-
Download ngrok for Windows.
-
Unzip the package and run ngrok.exe.
-
Replace the two {port-number} placeholder values in the following command with the port number you copied, and then run the command in the ngrok console.
ngrok http {port-number} -host-header=localhost:{port-number}
-
Copy the HTTPS URL that's shown in the console. You'll use this to configure your notification URL in the sample.
Keep the console open while testing. If you close it, the tunnel also closes and you'll need to generate a new URL and update the sample.
See Hosting without a tunnel and Why do I have to use a tunnel? for more information about using tunnels.
-
Follow these instructions to install the ASP.NET Core SignalR Javascript client package into the app.
-
Expose a public HTTPS notification endpoint. It can run on a service such as Microsoft Azure, or you can create a proxy web server by using ngrok or a similar tool.
-
Open the GraphWebhooks-Core.sln sample file in Visual Studio 2017.
-
In Solution Explorer, open the appsettings.json file in the root directory of the project.
- For the NotificationUrl key, replace ENTER_YOUR_URL with the HTTPS URL. Keep the /notification/listen portion.
If you're using ngrok, use the HTTPS URL that you copied. The value will look something like this:
"NotificationUrl": "https://2885f9c5.ngrok.io/notification/listen",
This is the url endpoint that will receive subscription validation callbacks and notification events from Graph, through the proxy server set up above (ngrok, for this sample).
-
Still within Solution Explorer, right-click on the project name and select Manage User Secrets. This app uses Secret Manager configuration in storing sensitive app data - ClientId and ClientSecret.
-
In the secret.json window that opens, paste the below code.
"AzureAd": { "ClientId": "ENTER_YOUR_APP_ID", "ClientSecret": "ENTER_YOUR_SECRET" }
-
For the ClientId key, replace ENTER_YOUR_APP_ID with the application ID of your registered Azure application.
-
For the ClientSecret key, replace ENTER_YOUR_SECRET with the key of your registered Azure application. Note that in production apps you should always use certificates as your application secrets, but for this sample we will use a simple shared secret password.
-
-
Make sure that the ngrok console is still running, then press F5 to build and run the solution in debug mode.
If you get errors while installing packages, make sure the local path where you placed the solution is not too long/deep. Moving the solution closer to the root drive resolves this issue.
-
Choose Sign in in the upper-right corner and sign in with a work or school account.
-
Consent to the View your basic profile and Sign in as you permissions.
-
On the sample home page, choose Grant admin consent. You'll be redirected to the adminconsent page.
-
Sign in as a tenant admin and consent to the Read mail in all mailboxes and Sign in and read user profile permissions. You'll be redirected back to the sample's home page.
At this point, any user in your tenant can sign in and create a subscription. If you don't grant admin permissions first, you'll receive an Unauthorized error. You'll need to open the sample in a new browser session because this sample caches the initial token.
-
Choose Create subscription. The Subscription page loads with information about the subscription.
This sample sets the subscription expiration to 15 minutes for testing purposes.
-
Choose the Watch for notifications button.
-
Send an email to your user account. The Notification page displays message properties. It may take several seconds for the page to update.
-
Optionally choose the Delete subscription button.
The following files contain code that's related to connecting to Microsoft Graph, creating subscriptions, and handling notifications.
appsettings.json
Contains values used for authentication, authorization and endpoint URLs.- secrets.json Contains the ClientId and ClientSecret used for authentication and authorization. To check whether these have been configured for the project run the following command from the directory in which the .csproj file exists:
dotnet user-secrets list
Startup.cs
Configures the app and the services it uses, including authentication.
AccountController.cs
Handles admin consent.NotificationController.cs
Receives notifications.SubscriptionContoller.cs
Creates and deletes subscriptions.
Notification.cs
Represents a change notification.MessageViewModel.cs
Defines the MessageViewModel that represents the data displayed in the Notification view.
GraphServiceClientFactory.cs
Initiates the SDK client used to interact with Microsoft Graph.SubscriptionStore.cs
Access layer for stored subscription information. The sample temporarily stores the info in HttpRuntime.Cache. Production apps will typically use some method of persistent storage.
-
Helper library containing a set of reusable classes that are useful in helping with the below:
- Authenticating and signing-in users with any Work, School or Microsoft Personal Accounts on the Microsoft identity platform v2.0 (AAD v2.0) using OpenId connect middleware and MSAL.NET.
- Handling sign-out and removing the account from MSAL.NET cache.
- Token acquisition on behalf of the signed in user.
- Bootstrapping the web resource from the
Startup.cs
file in the application by just calling a few methods.
Issue | Resolution |
---|---|
You get a 403 Forbidden response when you attempt to create a subscription. | Make sure that your app registration includes the Mail.Read application permission for Microsoft Graph (as described in the Register the app section) and that a tenant administrator has granted consent to the app. |
You do not receive notifications. | If you're using ngrok, you can use the web interface (http://127.0.0.1:4040) to see whether the notification is being received. If you're not using ngrok, monitor the network traffic using the tools your hosting service provides, or try using ngrok. If Microsoft Graph is not sending notifications, please open a Stack Overflow issue tagged [MicrosoftGraph]. Include the subscription ID, the time it was created, and the request ID from the response (if you have it). Known issue: Occasionally the notification is received, and the retrieved message is sent to NotificationService, but the SignalR client in this sample does not update. When this happens, it's usually the first notification after the subscription is created. |
You get a Subscription validation request timed out response. | This indicates that Microsoft Graph did not receive a validation reponse within 10 seconds. If you're using ngrok, make sure that your endpoint is accessible and that you specified your project's HTTP port for the tunnel (not HTTPS). |
You get errors while installing packages. | Make sure the local path where you placed the solution is not too long/deep. Moving the solution closer to the root drive resolves this issue. |
You get build errors related to Microsoft.AspNetCore.SignalR.Server | Type this command in the Package Manager Console: 'Install-Package Microsoft.AspNetCore.SignalR.Server -Version 0.2.0-rtm-22752 -Source https://dotnet.myget.org/F/aspnetcore-master/api/v3/index.json' |
The app opens to a Server Error in '/' Application. The resource cannot be found. browser page. | Make sure that a CSHTML view file isn't the active tab when you run the app from Visual Studio. |
If you'd like to contribute to this sample, see CONTRIBUTING.MD.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
We'd love to get your feedback about the Microsoft Graph Webhooks sample for ASP.NET Core. You can send your questions and suggestions to us in the Issues section of this repository.
Questions about Microsoft Graph in general should be posted to Stack Overflow. Make sure that your questions or comments are tagged with [MicrosoftGraph].
You can suggest changes for Microsoft Graph on UserVoice.
- Microsoft Graph Webhooks sample for ASP.NET 4.6 (Delegated permissions)
- Microsoft Graph Webhooks sample for Node.js (Delegated permissions)
- Working with Webhooks in Microsoft Graph
- Subscription resource
- Microsoft Graph documentation
Copyright (c) 2019 Microsoft. All rights reserved.