Skip to content

Commit e35c3ed

Browse files
authored
Roll Blazor into the Simple Auth article (#36650)
1 parent 93f1d03 commit e35c3ed

47 files changed

Lines changed: 333 additions & 39773 deletions

Some content is hidden

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

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

aspnetcore/security/authentication/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ Finbuckle.MultiTenant:
162162
* <xref:security/authorization/limitingidentitybyscheme>
163163
* <xref:security/authentication/policyschemes>
164164
* <xref:security/authorization/secure-data>
165-
* [Globally require authenticated users](xref:security/authorization/secure-data#rau)
165+
* [Globally require authenticated users](xref:security/authorization/secure-data#require-authenticated-users)
166166
* [GitHub issue on using multiple authentication schemes](https://github.com/dotnet/aspnetcore/issues/26002)
167167

168168
:::moniker-end
@@ -302,7 +302,7 @@ See the [Orchard Core](https://github.com/OrchardCMS/OrchardCore) source for an
302302
* <xref:security/authorization/limitingidentitybyscheme>
303303
* <xref:security/authentication/policyschemes>
304304
* <xref:security/authorization/secure-data>
305-
* [Globally require authenticated users](xref:security/authorization/secure-data#rau)
305+
* [Globally require authenticated users](xref:security/authorization/secure-data#require-authenticated-users)
306306
* [GitHub issue on using multiple authentication schemes](https://github.com/dotnet/aspnetcore/issues/26002)
307307

308308
:::moniker-end
@@ -440,7 +440,7 @@ ASP.NET Core framework doesn't have a built-in solution for multi-tenant authent
440440
* <xref:security/authorization/limitingidentitybyscheme>
441441
* <xref:security/authentication/policyschemes>
442442
* <xref:security/authorization/secure-data>
443-
* [Globally require authenticated users](xref:security/authorization/secure-data#rau)
443+
* [Globally require authenticated users](xref:security/authorization/secure-data#require-authenticated-users)
444444
* [GitHub issue on using multiple authentication schemes](https://github.com/dotnet/aspnetcore/issues/26002)
445445

446446
:::moniker-end

aspnetcore/security/authorization/policies.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ if (context.Resource is AuthorizationFilterContext mvcContext)
256256

257257
## Globally require all users to be authenticated
258258

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

261261
<a name="exs"></a>
262262

0 commit comments

Comments
 (0)