Skip to content

Commit 2cea778

Browse files
authored
Merge pull request #36841 from dotnet/main
Merge to Live
2 parents 57d1410 + e35c3ed commit 2cea778

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+345
-39776
lines changed

aspnetcore/fundamentals/error-handling-api.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Learn about error handling in ASP.NET Core APIs with Minimal APIs a
55
ai-usage: ai-assisted
66
ms.author: wpickett
77
monikerRange: '>= aspnetcore-7.0'
8-
ms.date: 08/15/2025
8+
ms.date: 03/04/2026
99
uid: fundamentals/error-handling-api
1010
---
1111

@@ -139,9 +139,18 @@ In the following code, `httpContext.Response.WriteAsync("Fallback: An error occu
139139
140140
The preceding code:
141141
142-
* Writes an error message with the fallback code if the `problemDetailsService` is unable to write a `ProblemDetails`. For example, an endpoint where the [Accept request header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Accept) specifies a media type that the `DefaulProblemDetailsWriter` does not support.
142+
* Writes an error message with the fallback code if the `problemDetailsService` is unable to write a `ProblemDetails`. For example, an endpoint where the [Accept request header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Accept) specifies a media type that the `DefaultProblemDetailsWriter` does not support.
143143
* Uses the [Exception Handler Middleware](#exception-handler).
144144
145+
> [!NOTE]
146+
> The `DefaultProblemDetailsWriter` supports the following media types in the `Accept` request header:
147+
>
148+
> * `application/json`
149+
> * `application/problem+json`
150+
> * Wildcard types such as `*/*` and `application/*`
151+
>
152+
> Non-JSON media types, such as `application/xml` or `text/html`, are **not** supported and trigger the fallback behavior.
153+
145154
The following sample is similar to the preceding except that it calls the [`Status Code Pages middleware`](#client-and-server-error-responses).
146155
147156
:::code language="csharp" source="~/fundamentals/minimal-apis/handle-errors/sample8/Program.cs" id="snippet_IProblemDetailsServiceWithStatusCodePageFallback" highlight="15":::
@@ -255,4 +264,4 @@ The contents of the response can be modified from outside of the controller usin
255264
256265
* [How to Use ModelState Validation in ASP.NET Core Web API](https://code-maze.com/aspnetcore-modelstate-validation-web-api/)
257266
* [View or download sample code](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/fundamentals/middleware/problem-details-service)
258-
* [Hellang.Middleware.ProblemDetails](https://www.nuget.org/packages/Hellang.Middleware.ProblemDetails/)
267+
* [Hellang.Middleware.ProblemDetails](https://www.nuget.org/packages/Hellang.Middleware.ProblemDetails/)

aspnetcore/includes/requireAuth.md

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
title: Simple authorization in ASP.NET Core MVC
3+
ai-usage: ai-assisted
4+
author: tdykstra
5+
description: Learn how to use the [Authorize] attribute to restrict access in ASP.NET Core MVC apps.
6+
ms.author: tdykstra
7+
ms.date: 03/05/2026
8+
uid: mvc/security/authorization/simple
9+
---
10+
# Simple authorization in ASP.NET Core MVC
11+
12+
Authorization in ASP.NET Core is controlled with the [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) and its various parameters. In its most basic form, applying the `[Authorize]` attribute to a Razor component, controller, action, or Razor Page, limits access to that component to authenticated users.
13+
14+
This article covers scenarios that pertain to MVC apps. For the primary coverage on this subject, see <xref:security/authorization/simple>.
15+
16+
## `[Authorize]` attribute
17+
18+
The following example limits access to authenticated users by specifying the [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute):
19+
20+
```csharp
21+
[Authorize]
22+
public class AccountController : Controller
23+
{
24+
public ActionResult Login() { ... }
25+
public ActionResult Logout() { ... }
26+
}
27+
```
28+
29+
The [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) also supports role-based or policy-based authorization. For role-based authorization, use the <xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute.Roles> parameter. In the following example, the user can only access the page if they're in the `Admin` or `Superuser` role:
30+
31+
```csharp
32+
[Authorize(Roles = "Admin, Superuser")]
33+
public class OrderController : Controller
34+
{
35+
...
36+
}
37+
```
38+
39+
For policy-based authorization, use the <xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute.Policy> parameter. In the following example, the user can only access the page if they satisfy the requirements of the `Over21` [authorization policy](xref:security/authorization/policies):
40+
41+
```csharp
42+
[Authorize(Policy = "Over21")]
43+
public class LicenseApplicationController : Controller
44+
{
45+
...
46+
}
47+
```
48+
49+
If neither <xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute.Roles> nor <xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute.Policy> is specified, [`[Authorize]`](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) uses the default policy:
50+
51+
* Authenticated (signed-in) users are authorized.
52+
* Unauthenticated (signed-out) users are unauthorized.
53+
54+
To apply authorization to an action rather than the controller, apply the [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) to the action. In the following example, only authenticated users can trigger a logout (call the `Logout` method):
55+
56+
```csharp
57+
public class AccountController : Controller
58+
{
59+
public ActionResult Login() { ... }
60+
61+
[Authorize]
62+
public ActionResult Logout() { ... }
63+
}
64+
```
65+
66+
Use the [`[AllowAnonymous]` attribute](xref:Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute) to allow access by non-authenticated users to individual actions:
67+
68+
```csharp
69+
[AllowAnonymous]
70+
```
71+
72+
> [!WARNING]
73+
> For MVC controllers, the [`[AllowAnonymous]` attribute](xref:Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute) bypasses authorization statements. If you combine `[AllowAnonymous]` and one or more `[Authorize]` attributes, the `[Authorize]` attributes are ignored. If you apply `[AllowAnonymous]` at the controller level:
74+
>
75+
> * Any authorization requirements from `[Authorize]` attributes on the same controller or action methods on the controller are ignored.
76+
> * Authentication middleware isn't short-circuited but doesn't need to succeed.
77+
78+
For information on how to require authentication for all app users, see <xref:security/authorization/secure-data#require-authenticated-users>.
79+
80+
## Additional resources
81+
82+
* <xref:security/authorization/simple>
83+
* <xref:razor-pages/security/authorization/simple>

aspnetcore/razor-pages/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ Add <xref:Microsoft.Extensions.DependencyInjection.MvcRazorPagesMvcCoreBuilderEx
598598
## Additional resources
599599

600600
* See [Get started with Razor Pages](xref:tutorials/razor-pages/razor-pages-start), which builds on this introduction.
601-
* [Authorize attribute and Razor Pages](xref:security/authorization/simple#aarp)
601+
* [`[Authorize]` attribute in Razor Pages apps](xref:razor-pages/security/authorization/simple#authorize-attribute-in-razor-pages-apps)
602602
* [Download or view sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/razor-pages/index/6.0sample)
603603
* <xref:index>
604604
* <xref:mvc/views/razor>

aspnetcore/razor-pages/index/includes/index35.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ Add <xref:Microsoft.Extensions.DependencyInjection.MvcRazorPagesMvcCoreBuilderEx
590590
## Additional resources
591591

592592
* See [Get started with Razor Pages](xref:tutorials/razor-pages/razor-pages-start), which builds on this introduction.
593-
* [Authorize attribute and Razor Pages](xref:security/authorization/simple#aarp)
593+
* [`[Authorize]` attribute in Razor Pages apps](xref:razor-pages/security/authorization/simple#authorize-attribute-in-razor-pages-apps)
594594
* [Download or view sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/razor-pages/index/3.0sample)
595595
* <xref:index>
596596
* <xref:mvc/views/razor>
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
---
2+
title: Simple authorization in ASP.NET Core Razor Pages
3+
ai-usage: ai-assisted
4+
author: tdykstra
5+
description: Learn how to use the [Authorize] attribute to restrict access in ASP.NET Core Razor Pages apps.
6+
ms.author: tdykstra
7+
ms.date: 03/05/2026
8+
uid: razor-pages/security/authorization/simple
9+
---
10+
# Simple authorization in ASP.NET Core Razor Pages
11+
12+
Authorization in ASP.NET Core is controlled with the [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) and its various parameters. In its most basic form, applying the `[Authorize]` attribute to a Razor component, controller, action, or Razor Page, limits access to that component to authenticated users.
13+
14+
This article covers scenarios that pertain to Razor Pages apps. For more information, see <xref:security/authorization/simple>.
15+
16+
## `[Authorize]` attribute
17+
18+
Apply the [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) to the page model class that derives from <xref:Microsoft.AspNetCore.Mvc.RazorPages.PageModel>. In the following example, only authenticated users can reach the `LogoutModel` page:
19+
20+
```csharp
21+
[Authorize]
22+
public class LogoutModel : PageModel
23+
{
24+
public async Task OnGetAsync() { ... }
25+
public async Task<IActionResult> OnPostAsync() { ... }
26+
}
27+
```
28+
29+
The [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) also supports role-based or policy-based authorization. For role-based authorization, use the <xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute.Roles> parameter. In the following example, the user can only access the page if they're in the `Admin` or `Superuser` role:
30+
31+
```csharp
32+
[Authorize(Roles = "Admin, Superuser")]
33+
public class OrderModel : PageModel
34+
{
35+
...
36+
}
37+
```
38+
39+
For policy-based authorization, use the <xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute.Policy> parameter. In the following example, the user can only access the page if they satisfy the requirements of the `Over21` [authorization policy](xref:security/authorization/policies):
40+
41+
```csharp
42+
[Authorize(Policy = "Over21")]
43+
public class LicenseApplicationModel : PageModel
44+
{
45+
...
46+
}
47+
```
48+
49+
If neither <xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute.Roles> nor <xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute.Policy> is specified, [`[Authorize]`](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) uses the default policy:
50+
51+
* Authenticated (signed-in) users are authorized.
52+
* Unauthenticated (signed-out) users are unauthorized.
53+
54+
For guidance on <xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute> and Razor Page handlers, see the [`[Authorize]` attribute in Razor Pages apps](#authorize-attribute-in-razor-pages-apps) section.
55+
56+
Use the [`[AllowAnonymous]` attribute](xref:Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute) to allow access by non-authenticated users to individual actions:
57+
58+
```csharp
59+
[AllowAnonymous]
60+
```
61+
62+
For information on how to require authentication for all app users, see <xref:security/authorization/secure-data#require-authenticated-users>.
63+
64+
## `[Authorize]` attribute in Razor Pages apps
65+
66+
The <xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute> can't be applied to Razor Page handlers. For example, the [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) can't be applied to `OnGet`, `OnPost`, or any other page handler. In a Razor Pages app, consider using an ASP.NET Core MVC controller for pages with different authorization requirements for different handlers. Using a controller when different authorization requirements are required is the least complex approach we recommend.
67+
68+
If you decide not to use an MVC controller, the following two approaches can be used to apply authorization to Razor Page handler methods:
69+
70+
* Use separate pages for page handlers requiring different authorization. Move shared content into one or more [partial views](xref:mvc/views/partial). When possible, this is the recommended approach.
71+
* For content that must share a common page, write a filter that performs authorization as part of <xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter.OnPageHandlerExecutionAsync%2A?displayProperty=nameWithType>. This approach is demonstrated by the following example.
72+
73+
The `AuthorizeIndexPageHandlerFilter` implements the authorization filter:
74+
75+
```csharp
76+
public class AuthorizeIndexPageHandlerFilter(
77+
IAuthorizationPolicyProvider policyProvider,
78+
IPolicyEvaluator policyEvaluator) : IAsyncPageFilter, IOrderedFilter
79+
{
80+
private readonly IAuthorizationPolicyProvider policyProvider =
81+
policyProvider;
82+
private readonly IPolicyEvaluator policyEvaluator = policyEvaluator;
83+
84+
// Run late in the execution pipeline
85+
public int Order => 10000;
86+
87+
public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context,
88+
PageHandlerExecutionDelegate next)
89+
{
90+
var attribute = context.HandlerMethod?.MethodInfo?
91+
.GetCustomAttribute<AuthorizePageHandlerAttribute>();
92+
93+
if (attribute is null)
94+
{
95+
await next();
96+
return;
97+
}
98+
99+
var policy = await AuthorizationPolicy
100+
.CombineAsync(policyProvider, new[] { attribute });
101+
102+
if (policy is null)
103+
{
104+
await next();
105+
return;
106+
}
107+
108+
var httpContext = context.HttpContext;
109+
var authenticateResult = await policyEvaluator
110+
.AuthenticateAsync(policy, httpContext);
111+
var authorizeResult = await policyEvaluator
112+
.AuthorizeAsync(policy, authenticateResult, httpContext,
113+
context.ActionDescriptor);
114+
115+
if (authorizeResult.Challenged)
116+
{
117+
context.Result = policy.AuthenticationSchemes.Count > 0
118+
? new ChallengeResult(policy.AuthenticationSchemes.ToArray())
119+
: new ChallengeResult();
120+
121+
return;
122+
}
123+
else if (authorizeResult.Forbidden)
124+
{
125+
context.Result = policy.AuthenticationSchemes.Count > 0
126+
? new ForbidResult(policy.AuthenticationSchemes.ToArray())
127+
: new ForbidResult();
128+
129+
return;
130+
}
131+
132+
await next();
133+
}
134+
135+
public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
136+
=> Task.CompletedTask;
137+
}
138+
```
139+
140+
The `AuthorizePageHandlerAttribute` provides an `[AuthorizePageHandler]` attribute to the app:
141+
142+
```csharp
143+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
144+
public class AuthorizePageHandlerAttribute(string policy = null)
145+
: Attribute, IAuthorizeData
146+
{
147+
public string Policy { get; set; } = policy;
148+
public string Roles { get; set; }
149+
public string AuthenticationSchemes { get; set; }
150+
}
151+
```
152+
153+
The `[AuthorizePageHandler]` attribute is applied to page handlers. In the following example, the attribute is set on the `OnPostAuthorized` page handler:
154+
155+
```csharp
156+
[TypeFilter(typeof(AuthorizeIndexPageHandlerFilter))]
157+
public class IndexModel : PageModel
158+
{
159+
...
160+
161+
[AuthorizePageHandler]
162+
public void OnPostAuthorized() { ... }
163+
}
164+
```
165+
166+
> [!WARNING]
167+
> The preceding approach does ***not***:
168+
>
169+
> * Compose with authorization attributes applied to the page, page model, or globally. Composing authorization attributes results in authentication and authorization executing multiple times when you have one more [`[Authorize]` attributes](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) or <xref:Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter> instances also applied to the page.
170+
> * Work in conjunction with the rest of the ASP.NET Core authentication and authorization system. Verify that this approach works correctly for the app.
171+
172+
There are no plans to support the [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) on Razor Page handlers.
173+
174+
## Additional resources
175+
176+
* <xref:security/authorization/simple>
177+
* <xref:mvc/security/authorization/simple>

aspnetcore/security/authentication/identity-configuration.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ builder.Services.Configure<PasswordHasherOptions>(option =>
148148

149149
## Globally require all users to be authenticated
150150

151-
[!INCLUDE[](~/includes/requireAuth.md)]
151+
For information on how to require authentication for all app users, see <xref:security/authorization/secure-data#require-authenticated-users>.
152152

153153
<a name="iss6"></a>
154154

@@ -296,6 +296,6 @@ services.Configure<PasswordHasherOptions>(option =>
296296

297297
## Globally require all users to be authenticated
298298

299-
[!INCLUDE[](~/includes/requireAuth.md)]
299+
For information on how to require authentication for all app users, see <xref:security/authorization/secure-data#require-authenticated-users>.
300300

301301
:::moniker-end

aspnetcore/security/authentication/identity.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ ASP.NET Core Identity:
1919

2020
Users can create an account with the login information stored in Identity or they can use an external login provider. Supported external login providers include [Facebook, Google, Microsoft Account, and Twitter](xref:security/authentication/social/index).
2121

22-
[!INCLUDE[](~/includes/requireAuth.md)]
22+
For information on how to require authentication for all app users, see <xref:security/authorization/secure-data#require-authenticated-users>.
2323

2424
The [Identity source code](https://github.com/dotnet/AspNetCore/tree/main/src/Identity) is available on GitHub. [Scaffold Identity](xref:security/authentication/scaffold-identity) and view the generated files to review the template interaction with Identity.
2525

aspnetcore/security/authentication/identity/includes/identity6.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ ASP.NET Core Identity:
99

1010
Users can create an account with the login information stored in Identity or they can use an external login provider. Supported external login providers include [Facebook, Google, Microsoft Account, and Twitter](xref:security/authentication/social/index).
1111

12-
[!INCLUDE[](~/includes/requireAuth.md)]
12+
For information on how to require authentication for all app users, see <xref:security/authorization/secure-data#require-authenticated-users>.
1313

1414
The [Identity source code](https://github.com/dotnet/AspNetCore/tree/main/src/Identity) is available on GitHub. [Scaffold Identity](xref:security/authentication/scaffold-identity) and view the generated files to review the template interaction with Identity.
1515

@@ -258,7 +258,7 @@ ASP.NET Core Identity:
258258

259259
Users can create an account with the login information stored in Identity or they can use an external login provider. Supported external login providers include [Facebook, Google, Microsoft Account, and Twitter](xref:security/authentication/social/index).
260260

261-
[!INCLUDE[](~/includes/requireAuth.md)]
261+
For information on how to require authentication for all app users, see <xref:security/authorization/secure-data#require-authenticated-users>.
262262

263263
The [Identity source code](https://github.com/dotnet/AspNetCore/tree/main/src/Identity) is available on GitHub. [Scaffold Identity](xref:security/authentication/scaffold-identity) and view the generated files to review the template interaction with Identity.
264264

0 commit comments

Comments
 (0)