Skip to content

Commit f3f4c83

Browse files
authored
Merge pull request #8907 from MicrosoftDocs/main
Auto push to live 2025-05-12 10:01:55
2 parents 431106d + c0248dc commit f3f4c83

File tree

9 files changed

+214
-97
lines changed

9 files changed

+214
-97
lines changed

.openpublishing.redirection.json

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13664,6 +13664,7 @@
1366413664
"source_path": "support/dynamics/gp/unapproved-pending-change-order-exist.md",
1366513665
"redirect_url": "/troubleshoot/dynamics/gp/welcome-gp"
1366613666
},
13667+
1366713668
{
1366813669
"source_path": "support/dynamics/gp/use-banked-paycodes-with-project-accounting.md",
1366913670
"redirect_url": "/troubleshoot/dynamics/gp/welcome-gp"
@@ -13686,11 +13687,16 @@
1368613687
},
1368713688
{
1368813689
"source_path": "support/windows-server/active-directory/troubleshoot-errors-join-computer-to-domain.md",
13689-
"redirect_url": "/troubleshoot/windows-server/active-directory/networking-errors-join-computer-domain"
13690+
"redirect_url": "/troubleshoot/windows-server/active-directory/domain-join-networking-errors"
1369013691
},
1369113692
{
1369213693
"source_path": "support/power-platform/power-automate/desktop-flows/troubleshoot-excel-errors.md",
1369313694
"redirect_url": "/troubleshoot/power-platform/power-automate/desktop-flows/office-automation/excel/troubleshoot-excel-errors"
13694-
}
13695+
},
13696+
{
13697+
"source_path": "support/entra/entra-id/mfa/authorization-request-denied-graph-api.md",
13698+
"redirect_url": "/troubleshoot/entra/entra-id/app-integration/troubleshoot-authorization-requestdenied-graph-api",
13699+
"redirect_document_id": false
13700+
}
1369513701
]
13696-
}
13702+
}
261 KB
Loading
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
---
2+
title: Use Serilog to Troubleshoot Protected Web API Authentication or Authorization Errors
3+
description: Provides a sample web API application to troubleshoot Microsoft Entra protected Web API authentication or authorization errors using Serilog logs.
4+
ms.date: 05/12/2025
5+
ms.service: entra-id
6+
ms.custom: sap:Developing or Registering apps with Microsoft identity platform
7+
ms.reviewer: bachoang, v-weizhu
8+
---
9+
# Use Serilog to troubleshoot Microsoft Entra protected Web API authentication or authorization errors
10+
11+
When a web API application calls a web API that's protected with Microsoft Entra ID, authentication or authorization errors might occur due to JwtBearer event validation failures. To troubleshoot this issue, this article introduces a sample web API application named [Net6WebAPILogging](https://github.com/bachoang/Net6WebAPILogging) to set and collect logs for JwtBearer events.
12+
13+
## Net6WebAPILogging sample application
14+
15+
This sample web API application assumes you already have a web API registered in Microsoft Entra ID. It uses Microsoft .NET 6 Framework and [Microsoft Identity Web](/entra/msal/dotnet/microsoft-identity-web/) NuGet package.
16+
17+
It uses the following methods to set and collect logs for JwtBearer events:
18+
19+
- Use the [JwtBearerEvents class](/dotnet/api/microsoft.aspnetcore.authentication.jwtbearer.jwtbearerevents) to configure middleware events. JWT Bearer token might fail to validate `OnTokenValidated`, `OnMessageReceived`, `OnAuthenticationFailed`, and `OnChalleenge` events.
20+
- [Set up logging for JwtBearer events](#set-up-logging-for-jwtbearer-events).
21+
- Use the [Serilog](https://serilog.net/) framework to log the `Debug` output to the console window and the local file whose path is specified in the **appsettings.json** file.
22+
23+
## Run the sample application
24+
25+
To run the sample application, you must perform the following steps:
26+
27+
### Step 1: Configure the application ID URI for a protected web API
28+
29+
To add the application ID URI for a web API, follow these steps:
30+
31+
1. In the Azure portal, navigate to the app registration of the web API.
32+
2. Select **Expose an API** under **Manage**.
33+
3. At the top of the page, select **Add** next to **Application ID URI**. The default is `api://<application-client-id>`.
34+
35+
:::image type="content" source="media/serilog-protected-web-api-authentication-authorization-errors/application-id-uri.png" alt-text="Screenshot that shows how to set the application ID URI in an app registration.":::
36+
5. Select **Save**.
37+
38+
### Step 2: Change the sample application configuration
39+
40+
Change the following information in the `AzureAd` section in the **appsettings.json** file with your own app registration information:
41+
42+
```json
43+
"AzureAd": {
44+
"Instance": "https://login.microsoftonline.com/",
45+
"Domain": "<tenant name>.onmicrosoft.com", // for example contoso.onmicrosoft.com
46+
"TenantId": "<tenant ID>",
47+
"ClientId": "<application-client-id>"
48+
},
49+
```
50+
51+
### Step 3: Change the sample application code
52+
53+
Change the `ValidAudiences` and `ValidIssuers` properties of the [TokenValidationParameters](/dotnet/api/microsoft.identitymodel.tokens.tokenvalidationparameters) class in the **Program.cs** file.
54+
55+
### Step 4: Configure Serilog
56+
57+
Configure Serilog in the `Serilog` section in the **appsettings.json** file as follows:
58+
59+
```json
60+
"Serilog": {
61+
"MinimumLevel": {
62+
"Default": "Information",
63+
"Override": {
64+
"Microsoft": "Debug",
65+
"Microsoft.Hosting.Lifetime": "Information"
66+
}
67+
},
68+
```
69+
70+
## Set up logging for JwtBearer events
71+
72+
Here's the sample **Program.cs** file that shows how to set up logging for the preceding events:
73+
74+
```csharp
75+
using Microsoft.AspNetCore.Authentication;
76+
using Microsoft.AspNetCore.Authentication.JwtBearer;
77+
using Microsoft.Identity.Web;
78+
using Microsoft.IdentityModel.Logging;
79+
using System.Diagnostics;
80+
using Serilog;
81+
82+
83+
// https://github.com/datalust/dotnet6-serilog-example
84+
85+
Log.Logger = new LoggerConfiguration()
86+
.WriteTo.Console()
87+
.CreateBootstrapLogger();
88+
89+
Log.Information("starting up");
90+
try
91+
{
92+
var builder = WebApplication.CreateBuilder(args);
93+
94+
builder.Host.UseSerilog((ctx, lc) => lc
95+
.WriteTo.Console()
96+
.ReadFrom.Configuration(ctx.Configuration));
97+
98+
// Add services to the container.
99+
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
100+
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
101+
102+
// Enable PII for logging
103+
IdentityModelEventSource.ShowPII = true;
104+
// Configure middleware events
105+
builder.Services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
106+
{
107+
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
108+
{
109+
ValidAudiences = new List<string> { "api://<application-client-id>", "<application-client-id>" },
110+
ValidIssuers = new List<string> { "https://sts.windows.net/<tenant ID>/", "https://login.microsoftonline.com/<tenant ID>/v2.0" }
111+
};
112+
options.Events = new JwtBearerEvents
113+
{
114+
OnTokenValidated = ctx =>
115+
{
116+
string message = "[OnTokenValidated]: ";
117+
message += $"token: {ctx.SecurityToken.ToString()}";
118+
Log.Information(message);
119+
return Task.CompletedTask;
120+
},
121+
OnMessageReceived = ctx =>
122+
{
123+
string message = "[OnMessageReceived]: ";
124+
ctx.Request.Headers.TryGetValue("Authorization", out var BearerToken);
125+
if (BearerToken.Count == 0)
126+
BearerToken = "no Bearer token sent\n";
127+
message += "Authorization Header sent: " + BearerToken + "\n";
128+
Log.Information(message);
129+
return Task.CompletedTask;
130+
},
131+
OnAuthenticationFailed = ctx =>
132+
{
133+
ctx.Response.StatusCode = StatusCodes.Status401Unauthorized;
134+
string message = $"[OnAuthenticationFailed]: {ctx.Exception.ToString()}";
135+
Log.Error(message);
136+
// Debug.WriteLine("[OnAuthenticationFailed]: Authentication failed with the following error: ");
137+
// Debug.WriteLine(ctx.Exception);
138+
return Task.CompletedTask;
139+
},
140+
OnChallenge = ctx =>
141+
{
142+
// Debug.WriteLine("[OnChallenge]: I can do stuff here! ");
143+
Log.Information("[OnChallenge]");
144+
return Task.CompletedTask;
145+
},
146+
OnForbidden = ctx =>
147+
{
148+
Log.Information("[OnForbidden]");
149+
return Task.CompletedTask;
150+
}
151+
};
152+
});
153+
154+
builder.Services.AddControllers();
155+
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
156+
// builder.Services.AddEndpointsApiExplorer();
157+
// builder.Services.AddSwaggerGen();
158+
159+
var app = builder.Build();
160+
161+
app.UseSerilogRequestLogging();
162+
// Configure the HTTP request pipeline.
163+
if (app.Environment.IsDevelopment())
164+
{
165+
// app.UseSwagger();
166+
// app.UseSwaggerUI();
167+
// do something
168+
}
169+
170+
app.UseHttpsRedirection();
171+
172+
app.UseAuthentication();
173+
app.UseAuthorization();
174+
175+
app.MapControllers();
176+
177+
app.Run();
178+
}
179+
catch (Exception ex)
180+
{
181+
Log.Fatal(ex, "Unhandled exception");
182+
}
183+
finally
184+
{
185+
Log.Information("Shut down complete");
186+
Log.CloseAndFlush();
187+
}
188+
```
189+
190+
## References
191+
192+
[Tutorial: Build and secure an ASP.NET Core web API with the Microsoft identity platform](/entra/identity-platform/tutorial-web-api-dotnet-core-build-app)
193+
194+
[!INCLUDE [Azure Help Support](../../../includes/third-party-disclaimer.md)]
195+
196+
[!INCLUDE [Azure Help Support](../../../includes/azure-help-support.md)]

support/entra/entra-id/dir-dmns-obj/cannot-delete-directory-azure-portal.md

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: Fixes an issue in which you can't delete a directory from the Micro
44
ms.date: 05/22/2020
55
ms.reviewer: willfid
66
ms.service: entra-id
7-
ms.custom: sap:Directory Management, has-azure-ad-ps-ref
7+
ms.custom: sap:Directory Management, no-azure-ad-ps-ref
88
---
99
# Can't delete a directory through the Azure Management Portal
1010

@@ -91,22 +91,20 @@ If you have an Azure subscription, make sure that your Azure subscription is not
9191

9292
To learn how to remove applications from your directory, read [Adding, updating, and removing an application](/azure/active-directory/develop/quickstart-register-app)
9393

94-
[!INCLUDE [Azure AD PowerShell deprecation note](~/../support/reusable-content/msgraph-powershell/includes/aad-powershell-deprecation-note.md)]
94+
You may also have to remove additional service principals. Use [Microsoft Graph PowerShell](/powershell/microsoftgraph/installation) to remove all service principals:
9595

96-
You may also have to remove additional service principals. Use Azure Active Directory module for Windows PowerShell to remove all service principals. To do this, follow these steps:
97-
98-
1. Open Azure Active Directory module for Windows PowerShell.
99-
2. Connect to the Microsoft Online Service.
100-
3. Run the following command:
96+
1. [Install Microsoft Graph PowerShell](/powershell/microsoftgraph/installation).
97+
2. Run the `Remove-MgServicePrincipal` command to remove all service principals. This command requires at least the `Application.ReadWrite.All` permission. For more information, see [Remove-MgServicePrincipal](/powershell/module/microsoft.graph.applications/remove-mgserviceprincipal?view=graph-powershell-1.0&preserve-view=true).
10198

10299
```powershell
103-
Get-MsolServicePrincipal | Remove-MsolServicePrincipal
100+
Connect-MgGraph -Scopes "Application.ReadWrite.All" -tenant <tenant-ID>
101+
Get-MgServicePrincipal | ForEach-Object { Remove-MgServicePrincipal -ServicePrincipalId $_.Id }
104102
```
105103
106104
> [!NOTE]
107105
> You may receive an error when you remove some service principals. These principals can't be removed. However, this does not prevent you from deleting your directory. The error that you receive may resemble the following:
108106
>
109-
> Remove-MsolServicePrincipal : Invalid value for parameter. Parameter Name: appPrincipalId.
107+
> Remove-MgServicePrincipal: Specified App Principal ID is Microsoft Internal.
110108
111109
## Directory has one or more Multi-Factor Authentication providers
112110

support/entra/entra-id/mfa/authorization-request-denied-graph-api.md

Lines changed: 0 additions & 81 deletions
This file was deleted.
Binary file not shown.
Binary file not shown.

support/entra/entra-id/toc.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969
href: app-integration/package-inspector-msal-android-native.md
7070
- name: Repeated login prompts in iOS MSAL implementation
7171
href: app-integration/repeat-login-prompts-in-msal-ios-app.md
72+
- name: Troubleshoot protected Web API authentication or authorization errors with Serilog
73+
href: app-integration/serilog-protected-web-api-authentication-authorization-errors.md
7274
- name: WIF10201 No valid key mapping found
7375
href: app-integration/troubleshoot-wif10201-no-validkey-securitytoken-mvc.md
7476

@@ -265,8 +267,6 @@
265267
href: mfa/text-voice-call-verification-code-mfa-not-send.md
266268
- name: Passwords
267269
items:
268-
- name: Authorization_RequestDenied error when changing password
269-
href: mfa/authorization-request-denied-graph-api.md
270270
- name: Can't verify account when resetting password
271271
href: user-prov-sync/could-not-verify-account-reset-pwd.md
272272
- name: Federated user is forced to sign in

support/entra/entra-id/welcome-entra-id.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ landingContent:
2121
linkLists:
2222
- linkListType: how-to-guide
2323
links:
24-
- text: Authorization_RequestDenied error when changing password
25-
url: mfa/authorization-request-denied-graph-api.md
2624
- text: Can't authenticate using ADAL
2725
url: mfa/adal-authenticate-android-devices-fail.md
2826
- text: Code 403 Forbidden error when using SSO

0 commit comments

Comments
 (0)