Skip to content

Commit acf6984

Browse files
author
Simonx Xu
authored
Merge pull request #9284 from AmandaAZ/Branch-CI5822
AB#5822: Convert blog post to article
2 parents a9965e4 + da363b6 commit acf6984

File tree

7 files changed

+176
-0
lines changed

7 files changed

+176
-0
lines changed

support/entra/entra-id/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,8 @@
341341
href: users-groups-entra-apis/b2c-or-tenant-premium-license-sign-in-activities.md
342342
- name: Problem with using the Graph SDK - libraries
343343
items:
344+
- name: Enable logging for MSAL.NET and Microsoft Graph SDK
345+
href: users-groups-entra-apis/enable-logging-for-msal-microsoft-graph.md
344346
- name: IDX14102 error - Unable to decode the header
345347
href: users-groups-entra-apis/unable-to-decode-header-error.md
346348
- name: Python scripts making requests are detected as web crawlers
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
---
2+
title: Enable Logging for MSAL.NET and Microsoft Graph SDK
3+
description: Introduces how to enable logging for both MSAL.NET and Microsoft Graph SDK.
4+
ms.reviewer: bachoang, v-weizhu
5+
ms.service: entra-id
6+
ms.date: 07/16/2025
7+
ms.custom: sap:Problem with using the Graph SDK - libraries
8+
ms.topic: how-to
9+
---
10+
# How to enable logging for MSAL.NET and Microsoft Graph SDK
11+
12+
[Microsoft Graph SDK](/graph/sdks/sdks-overview) has the ability to log complete HTTP requests and responses. The way this logging mechanism works is by implementing a custom [HttpClient Message handler](https://visualstudiomagazine.com/articles/2014/08/01/creating-custom-httpclient-handlers.aspx) to intercept every HTTP request and response between the client application and the Microsoft Graph Service. Besides hooking into the processing pipeline of the `GraphServiceClient` class to do request and response tracing, you can also configure proxy information. For more information, see [Customize the Microsoft Graph SDK service client](/graph/sdks/customize-client?tabs=csharp). MSAL.NET is used in the authentication provider of the `GraphServiceClient` class. Consequently, [logging](/azure/active-directory/develop/msal-logging-dotnet) in this library can provide valuable insight into authentication failures.
13+
14+
This article explains how to enable logging for both MSAL.NET and Microsoft Graph SDK by using a [.NET Core 3.0 console application sample](https://github.com/bachoang/MSGraphLoggingSample).
15+
16+
## Logging techniques
17+
18+
Different logging approaches are used to write log entries to Azure Blob Storage for MSAL.NET logging and Microsoft Graph SDK logging. The logging mechanisms provide insights into HTTP requests and responses, as well as authentication failures, which are invaluable for debugging and troubleshooting.
19+
20+
### MSAL.NET logging
21+
22+
For MSAL.NET logging, the [Azure Blob Storage client SDK](/azure/storage/blobs/storage-quickstart-blobs-dotnet) (v12) is used to write log entries into an Azure Blob.
23+
24+
### Microsoft Graph SDK logging
25+
26+
For Microsoft Graph SDK logging, the [Serilog](https://serilog.net/) library is used. Serilog offers various logging providers, known as "sinks," that support different logging environments such as Application Insight, DocumentDB, and Event Hubs.
27+
28+
In the following code, three logging sinks are configured: console logger, file logger, and Azure Blob Storage logger. You don't have to use all three and can add new one(s) or comment out the providers you don't need.
29+
30+
```csharp
31+
Log.Logger = new LoggerConfiguration()
32+
.MinimumLevel.Debug()
33+
.WriteTo.Console() // Serilog console logging
34+
.WriteTo.File(LoggingLocalPath, rollingInterval: RollingInterval.Day) // Serilog file logging
35+
.WriteTo.AzureBlobStorage(AzureStorageConnection, Serilog.Events.LogEventLevel.Verbose, MSGraphAzureBlobContainerName, MSGraphAzureBlobName) // Serilog Azure Blob Storage logging
36+
.CreateLogger();
37+
```
38+
39+
> [!NOTE]
40+
> When the Serilog Azure Blob Storage sink is used for both MSAL.NET and Microsoft Graph SDK logging, you might encounter an authentication issue where the authentication prompt window fails to appear.
41+
42+
## Prerequisites for running the sample application
43+
44+
Before running the sample application, ensure the following prerequisites are met.
45+
46+
### Application registration
47+
48+
1. Register the sample application in Microsoft Entra ID.
49+
50+
During the application registration, configure `http://localhost` as a redirect URI under the **Mobile and desktop applications** platform. This URI is required for .NET Core applications.
51+
52+
:::image type="content" source="media/enable-logging-for-msal-and-microsoft-graph/set-redirect-uri.png" alt-text="Screenshot that shows setting a redirect URI":::
53+
54+
2. Configure these delegated Microsoft Graph permissions in **API permissions**:
55+
56+
- **User.Read.All**
57+
- **Application.ReadWrite.All**
58+
59+
3. Grant admin consent to these permissions because the sample application uses the following Microsoft Graph requests to get the signed-in user information and create an app registration:
60+
61+
- `GET https://graph.microsoft.com/beta/me`
62+
- `POST https://graph.microsoft.com/beta/applications`
63+
64+
> [!NOTE]
65+
> Ensure the signed-in user has one of these administrative roles: Application Developer, Application Administrator, Cloud Application Administrator, or Global Administrator; otherwise, the application creation might fail due to insufficient permissions. For a list of built-in Microsoft Entra roles, see [Microsoft Entra built-in roles](/entra/identity/role-based-access-control/permissions-reference) .
66+
67+
### Azure Storage
68+
69+
Create an Azure Storage account for storing MSAL.NET and Microsoft Graph SDK logs as Azure Blobs. For read/write access to Azure Storage, you can use a connection string in **Key 1** or **Key 2** under **Access keys**.
70+
71+
:::image type="content" source="media/enable-logging-for-msal-and-microsoft-graph/connection-string-under-access-keys.png" alt-text="Screenshot that shows connection strings under 'Access keys'":::
72+
73+
### Application code
74+
75+
The complete sample code is available in this [GitHub repository](https://github.com/bachoang/MSGraphLoggingSample). Configuration options are stored in the following `appsettings.json` file. The sample application uses a code snippet from [this article](../app-integration/get-signed-in-users-groups-in-access-token.md) to read configuration settings from the `appsettings.json` file. It relies on the Microsoft Graph beta endpoint, so it references the Microsoft.Graph.Beta package; for v1 endpoint, use the Microsoft.Graph package. For more information, see [Use the Microsoft Graph SDKs with the beta API](/graph/sdks/use-beta).
76+
77+
```json
78+
{
79+
"Azure": {
80+
"ClientId": "",
81+
"TenantId": "",
82+
"MSALAzureBlobContainerName": "msallogs",
83+
"MSALAzureBlobName": "MsalLog.txt",
84+
"MSGraphAzureBlobContainerName": "msgraphlogs",
85+
"MSGraphAzureBlobName": "{yyyy}-{MM}-{dd}-msgraphlog.txt",
86+
"LoggingLocalPath": "C:/temp/msgraphlog.txt",
87+
"AzureStorageConnection": "",
88+
"Scopes": [ "https://graph.microsoft.com/.default" ]
89+
}
90+
}
91+
```
92+
93+
The sample application uses both `GET` and `POST` requests to show logging of the complete HTTP requests and responses, including headers and body. The following four helper functions are used to get the information for each part. Any function can be commented out if the corresponding information isn't required.
94+
95+
:::image type="content" source="media/enable-logging-for-msal-and-microsoft-graph/helper-functions.png" alt-text="Screenshot that shows four helper functions":::
96+
97+
These helper functions are used in the logging `HttpClient` message handler as shown here. Requests are logged before calling the `DelegatingHandler.SendAsync` method and responses are logged after the call.
98+
99+
```csharp
100+
public class SeriLoggingHandler : DelegatingHandler
101+
{
102+
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage httpRequest, CancellationToken cancellationToken)
103+
{
104+
HttpResponseMessage response = null;
105+
try
106+
{
107+
Log.Information("sending Graph Request");
108+
Log.Debug(GetRequestHeader(httpRequest));
109+
Log.Debug(GetRequestBody(httpRequest));
110+
response = await base.SendAsync(httpRequest, cancellationToken);
111+
Log.Information("Receiving Response:");
112+
Log.Debug(GetResponseHeader(response));
113+
Log.Debug(GetResponseBody(response));
114+
}
115+
catch (Exception ex)
116+
{
117+
Log.Error(ex, "Something went wrong");
118+
if (response.Content != null)
119+
{
120+
await response.Content.ReadAsByteArrayAsync();// Drain response content to free connections.
121+
}
122+
}
123+
return response;
124+
}
125+
}
126+
```
127+
128+
The following code shows how to set up the `GraphServcieClient` class to use the logging handler:
129+
130+
```csharp
131+
IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
132+
.Create(ClientId)
133+
.WithTenantId(TenantId)
134+
// Enable MSAL logging
135+
.WithLogging(MSALlogger, Microsoft.Identity.Client.LogLevel.Verbose, true)
136+
.WithRedirectUri("http://localhost")
137+
.Build();
138+
139+
InteractiveAuthenticationProvider authProvider = new InteractiveAuthenticationProvider(publicClientApplication, Scopes);
140+
141+
// get the default list of handlers and add the logging handler to the list
142+
var handlers = GraphClientFactory.CreateDefaultHandlers(authProvider);
143+
144+
// Remove Compression handler
145+
var compressionHandler =
146+
handlers.Where(h => h is CompressionHandler).FirstOrDefault();
147+
handlers.Remove(compressionHandler);
148+
149+
// Add SeriLog logger
150+
handlers.Add(new SeriLoggingHandler());
151+
152+
InitializeBlobStorageForMSAL().Wait();
153+
154+
var httpClient = GraphClientFactory.Create(handlers);
155+
GraphServiceClient graphClient = new GraphServiceClient(httpClient);
156+
```
157+
158+
> [!CAUTION]
159+
> This sample logs sensitive information, including Personally Identifying Information (PII) and access tokens. Be cautious when sharing debug logs.
160+
161+
## Check MSAL.NET and Microsoft Graph logs
162+
163+
After you run the sample application, Microsoft Graph requests and responses should appear in:
164+
165+
- The console window.
166+
- The directory location configured in the `appsettings.json` file. Log file names include the date, as shown here:
167+
168+
:::image type="content" source="media/enable-logging-for-msal-and-microsoft-graph/local-microsoft-graph-logs.png" alt-text="Screenshot that shows local logs":::
169+
170+
For Azure Blob Storage logging, the logs are in the `msallogs` and `msgraphlogs` containers:
171+
172+
:::image type="content" source="media/enable-logging-for-msal-and-microsoft-graph/azure-blob-storage-logs.png" alt-text="Screenshot that shows Azure Blob Storage logs":::
173+
174+
[!INCLUDE [Azure Help Support](../../../includes/azure-help-support.md)]
40.4 KB
Loading
Loading
40.2 KB
Loading
35.4 KB
Loading
58.5 KB
Loading

0 commit comments

Comments
 (0)