Skip to content

Commit 40fe514

Browse files
authored
Merge pull request #36920 from dotnet/main
Merge to Live
2 parents 05e8336 + 315994b commit 40fe514

84 files changed

Lines changed: 206 additions & 1552 deletions

File tree

Some content is hidden

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

.openpublishing.redirection.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,6 +1678,11 @@
16781678
"source_path": "aspnetcore/security/authorization/iard.md",
16791679
"redirect_url": "/aspnet/core/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata",
16801680
"redirect_document_id": false
1681+
},
1682+
{
1683+
"source_path": "aspnetcore/security/authorization/razor-pages-authorization.md",
1684+
"redirect_url": "/aspnet/core/razor-pages/security/authorization/conventions",
1685+
"redirect_document_id": false
16811686
}
16821687
]
16831688
}

aspnetcore/blazor/security/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ If authorization rule enforcement and the security of data and code must be guar
3030

3131
:::moniker-end
3232

33-
[Razor Pages authorization conventions](xref:security/authorization/razor-pages-authorization) don't apply to routable Razor components. If a non-routable Razor component is [embedded in a page of a Razor Pages app](xref:blazor/components/integration), the page's authorization conventions indirectly affect the Razor component along with the rest of the page's content.
33+
[Razor Pages authorization conventions](xref:razor-pages/security/authorization/conventions) don't apply to routable Razor components. If a non-routable Razor component is [embedded in a page of a Razor Pages app](xref:blazor/components/integration), the page's authorization conventions indirectly affect the Razor component along with the rest of the page's content.
3434

3535
:::moniker range="< aspnetcore-8.0"
3636

aspnetcore/razor-pages/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ The configuration and settings in following sections is not required by most app
579579
To configure advanced options, use the <xref:Microsoft.Extensions.DependencyInjection.MvcServiceCollectionExtensions.AddRazorPages%2A> overload that configures <xref:Microsoft.AspNetCore.Mvc.RazorPages.RazorPagesOptions>:
580580
[!code-csharp[](~/razor-pages/index/6.0sample/RazorPagesContacts/Program.cs?name=snippet_ac&highlight=5-9)]
581581

582-
Use the <xref:Microsoft.AspNetCore.Mvc.RazorPages.RazorPagesOptions> to set the root directory for pages, or add application model conventions for pages. For more information on conventions, see [Razor Pages authorization conventions](xref:security/authorization/razor-pages-authorization).
582+
Use the <xref:Microsoft.AspNetCore.Mvc.RazorPages.RazorPagesOptions> to set the root directory for pages, or add application model conventions for pages. For more information on conventions, see [Razor Pages authorization conventions](xref:razor-pages/security/authorization/conventions).
583583

584584
To precompile views, see [Razor view compilation](xref:mvc/views/view-compilation).
585585

@@ -604,7 +604,7 @@ Add <xref:Microsoft.Extensions.DependencyInjection.MvcRazorPagesMvcCoreBuilderEx
604604
* <xref:mvc/views/razor>
605605
* <xref:mvc/controllers/areas>
606606
* <xref:tutorials/razor-pages/razor-pages-start>
607-
* <xref:security/authorization/razor-pages-authorization>
607+
* <xref:razor-pages/security/authorization/conventions>
608608
* <xref:razor-pages/razor-pages-conventions>
609609
* <xref:test/razor-pages-tests>
610610
* <xref:mvc/views/partial>

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ To configure advanced options, use the <xref:Microsoft.Extensions.DependencyInje
571571

572572
[!code-csharp[](~/razor-pages/index/3.0sample/RazorPagesContacts/StartupRPoptions.cs?name=snippet)]
573573

574-
Use the <xref:Microsoft.AspNetCore.Mvc.RazorPages.RazorPagesOptions> to set the root directory for pages, or add application model conventions for pages. For more information on conventions, see [Razor Pages authorization conventions](xref:security/authorization/razor-pages-authorization).
574+
Use the <xref:Microsoft.AspNetCore.Mvc.RazorPages.RazorPagesOptions> to set the root directory for pages, or add application model conventions for pages. For more information on conventions, see [Razor Pages authorization conventions](xref:razor-pages/security/authorization/conventions).
575575

576576
To precompile views, see [Razor view compilation](xref:mvc/views/view-compilation).
577577

@@ -596,7 +596,7 @@ Add <xref:Microsoft.Extensions.DependencyInjection.MvcRazorPagesMvcCoreBuilderEx
596596
* <xref:mvc/views/razor>
597597
* <xref:mvc/controllers/areas>
598598
* <xref:tutorials/razor-pages/razor-pages-start>
599-
* <xref:security/authorization/razor-pages-authorization>
599+
* <xref:razor-pages/security/authorization/conventions>
600600
* <xref:razor-pages/razor-pages-conventions>
601601
* <xref:test/razor-pages-tests>
602602
* <xref:mvc/views/partial>

aspnetcore/razor-pages/razor-pages-conventions.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ The Page filter (<xref:Microsoft.AspNetCore.Mvc.Filters.IPageFilter>) is a filte
288288
## Additional resources
289289

290290
* [Razor Pages Routing](https://www.learnrazorpages.com/razor-pages/routing)
291-
* <xref:security/authorization/razor-pages-authorization>
291+
* <xref:razor-pages/security/authorization/conventions>
292292
* <xref:mvc/controllers/areas#areas-with-razor-pages>
293293

294294
:::moniker-end
@@ -569,7 +569,7 @@ The Page filter (<xref:Microsoft.AspNetCore.Mvc.Filters.IPageFilter>) is a filte
569569

570570
## Additional resources
571571

572-
* <xref:security/authorization/razor-pages-authorization>
572+
* <xref:razor-pages/security/authorization/conventions>
573573
* <xref:mvc/controllers/areas#areas-with-razor-pages>
574574

575575
:::moniker-end
@@ -825,7 +825,7 @@ The Page filter (<xref:Microsoft.AspNetCore.Mvc.Filters.IPageFilter>) is a filte
825825

826826
## Additional resources
827827

828-
* <xref:security/authorization/razor-pages-authorization>
828+
* <xref:razor-pages/security/authorization/conventions>
829829
* <xref:mvc/controllers/areas#areas-with-razor-pages>
830830

831831
:::moniker-end
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
---
2+
title: Razor Pages authorization conventions in ASP.NET Core
3+
author: wadepickett
4+
description: Learn how to control access to pages with conventions that authorize users and allow anonymous users to access pages or folders of pages.
5+
monikerRange: '>= aspnetcore-2.1'
6+
ms.author: wpickett
7+
ms.custom: mvc
8+
ms.date: 03/25/2026
9+
uid: razor-pages/security/authorization/conventions
10+
---
11+
# Razor Pages authorization conventions in ASP.NET Core
12+
13+
One way to control access in a Razor Pages app is to use authorization conventions at startup. These conventions allow the app to authorize users and allow anonymous users to access individual pages or folders of pages. The conventions described in this article automatically apply [authorization filters](xref:mvc/controllers/filters#authorization-filters) to control access.
14+
15+
[View or download sample code](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/security/authorization/RazorPagesAuthorization) ([how to download](xref:fundamentals/index#how-to-download-a-sample))
16+
17+
The sample app uses [cookie authentication without ASP.NET Core Identity](xref:security/authentication/cookie). To use ASP.NET Core Identity, follow the guidance in <xref:security/authentication/identity>.
18+
19+
## Require authorization to access a page
20+
21+
Use the <xref:Microsoft.Extensions.DependencyInjection.PageConventionCollectionExtensions.AuthorizePage%2A> convention to add an <xref:Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter> to the page at the specified path:
22+
23+
:::moniker range=">= aspnetcore-10.0"
24+
25+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/RazorPagesAuthorization/10.x/AuthorizationSample/Program.cs" id="snippet1" highlight="3":::
26+
27+
:::moniker-end
28+
29+
:::moniker range=">= aspnetcore-3.0 < aspnetcore-10.0"
30+
31+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/RazorPagesAuthorization/3.x/AuthorizationSample/Startup.cs" id="snippet1" highlight="3":::
32+
33+
:::moniker-end
34+
35+
:::moniker range="< aspnetcore-3.0"
36+
37+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/RazorPagesAuthorization/2.x/AuthorizationSample/Startup.cs" id="snippet1" highlight="2,4":::
38+
39+
:::moniker-end
40+
41+
The specified path is the View Engine path, which is the Razor Pages root relative path without an extension and containing only forward slashes.
42+
43+
To specify an [authorization policy](xref:security/authorization/policies), use an [`AuthorizePage` overload](xref:Microsoft.Extensions.DependencyInjection.PageConventionCollectionExtensions.AuthorizePage%2A):
44+
45+
```csharp
46+
options.Conventions.AuthorizePage("/Contact", "AtLeast21");
47+
```
48+
49+
> [!NOTE]
50+
> An <xref:Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter> can be applied to a page model class with the `[Authorize]` filter attribute. For more information, see <xref:razor-pages/filter#authorize-filter-attribute>.
51+
52+
## Require authorization to access a folder of pages
53+
54+
Use the <xref:Microsoft.Extensions.DependencyInjection.PageConventionCollectionExtensions.AuthorizeFolder%2A> convention to add an <xref:Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter> to all of the pages in a folder at the specified path:
55+
56+
:::moniker range=">= aspnetcore-10.0"
57+
58+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/RazorPagesAuthorization/10.x/AuthorizationSample/Program.cs" id="snippet1" highlight="4":::
59+
60+
:::moniker-end
61+
62+
:::moniker range=">= aspnetcore-3.0 < aspnetcore-10.0"
63+
64+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/RazorPagesAuthorization/3.x/AuthorizationSample/Startup.cs" id="snippet1" highlight="4":::
65+
66+
:::moniker-end
67+
68+
:::moniker range="< aspnetcore-3.0"
69+
70+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/RazorPagesAuthorization/2.x/AuthorizationSample/Startup.cs" id="snippet1" highlight="2,5":::
71+
72+
:::moniker-end
73+
74+
The specified path is the View Engine path, which is the Razor Pages root relative path containing only forward slashes.
75+
76+
To specify an [authorization policy](xref:security/authorization/policies), use an [`AuthorizeFolder` overload](xref:Microsoft.Extensions.DependencyInjection.PageConventionCollectionExtensions.AuthorizeFolder%2A):
77+
78+
```csharp
79+
options.Conventions.AuthorizeFolder("/Private", "AtLeast21");
80+
```
81+
82+
## Require authorization to access an area page
83+
84+
Use the <xref:Microsoft.Extensions.DependencyInjection.PageConventionCollectionExtensions.AuthorizeAreaPage%2A> convention to add an <xref:Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter> to the area page at the specified path:
85+
86+
```csharp
87+
options.Conventions.AuthorizeAreaPage("Identity", "/Manage/Accounts");
88+
```
89+
90+
The page name is the path of the file without an extension relative to the pages root directory for the specified area. For example, the page name for the file `Areas/Identity/Pages/Manage/Accounts.cshtml` is `/Manage/Accounts`.
91+
92+
To specify an [authorization policy](xref:security/authorization/policies), use an [`AuthorizeAreaPage` overload](xref:Microsoft.Extensions.DependencyInjection.PageConventionCollectionExtensions.AuthorizeAreaPage%2A):
93+
94+
```csharp
95+
options.Conventions.AuthorizeAreaPage("Identity", "/Manage/Accounts", "AtLeast21");
96+
```
97+
98+
## Require authorization to access a folder of areas
99+
100+
Use the <xref:Microsoft.Extensions.DependencyInjection.PageConventionCollectionExtensions.AuthorizeAreaFolder%2A> convention to add an <xref:Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter> to all of the areas in a folder at the specified path:
101+
102+
```csharp
103+
options.Conventions.AuthorizeAreaFolder("Identity", "/Manage");
104+
```
105+
106+
The folder path is the path of the folder relative to the pages root directory for the specified area. For example, the folder path for the files under `Areas/Identity/Pages/Manage/` is `/Manage`.
107+
108+
To specify an [authorization policy](xref:security/authorization/policies), use an [`AuthorizeAreaFolder` overload](xref:Microsoft.Extensions.DependencyInjection.PageConventionCollectionExtensions.AuthorizeAreaFolder%2A):
109+
110+
```csharp
111+
options.Conventions.AuthorizeAreaFolder("Identity", "/Manage", "AtLeast21");
112+
```
113+
114+
## Allow anonymous access to a page
115+
116+
Use the <xref:Microsoft.Extensions.DependencyInjection.PageConventionCollectionExtensions.AllowAnonymousToPage%2A> convention to add an <xref:Microsoft.AspNetCore.Mvc.Authorization.AllowAnonymousFilter> to a page at the specified path:
117+
118+
:::moniker range=">= aspnetcore-10.0"
119+
120+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/RazorPagesAuthorization/10.x/AuthorizationSample/Program.cs" id="snippet1" highlight="5":::
121+
122+
:::moniker-end
123+
124+
:::moniker range=">= aspnetcore-3.0 < aspnetcore-10.0"
125+
126+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/RazorPagesAuthorization/3.x/AuthorizationSample/Startup.cs" id="snippet1" highlight="5":::
127+
128+
:::moniker-end
129+
130+
:::moniker range="< aspnetcore-3.0"
131+
132+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/RazorPagesAuthorization/2.x/AuthorizationSample/Startup.cs" id="snippet1" highlight="2,6":::
133+
134+
:::moniker-end
135+
136+
The specified path is the View Engine path, which is the Razor Pages root relative path without an extension and containing only forward slashes.
137+
138+
## Allow anonymous access to a folder of pages
139+
140+
Use the <xref:Microsoft.Extensions.DependencyInjection.PageConventionCollectionExtensions.AllowAnonymousToFolder%2A> convention to add an <xref:Microsoft.AspNetCore.Mvc.Authorization.AllowAnonymousFilter> to all of the pages in a folder at the specified path:
141+
142+
:::moniker range=">= aspnetcore-10.0"
143+
144+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/RazorPagesAuthorization/10.x/AuthorizationSample/Program.cs" id="snippet1" highlight="6":::
145+
146+
:::moniker-end
147+
148+
:::moniker range=">= aspnetcore-3.0 < aspnetcore-10.0"
149+
150+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/RazorPagesAuthorization/3.x/AuthorizationSample/Startup.cs" id="snippet1" highlight="6":::
151+
152+
:::moniker-end
153+
154+
:::moniker range="< aspnetcore-3.0"
155+
156+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/RazorPagesAuthorization/2.x/AuthorizationSample/Startup.cs" id="snippet1" highlight="2,7":::
157+
158+
:::moniker-end
159+
160+
The specified path is the View Engine path, which is the Razor Pages root relative path without an extension and containing only forward slashes.
161+
162+
## Note on combining authorized and anonymous access
163+
164+
The app can specify that a folder of pages requires authorization and that a page within that folder allows anonymous access:
165+
166+
```csharp
167+
// This works.
168+
.AuthorizeFolder("/Private").AllowAnonymousToPage("/Private/Public")
169+
```
170+
171+
The reverse, however, isn't valid. The app can't declare a folder of pages for anonymous access and specify a page within that folder that requires authorization:
172+
173+
```csharp
174+
// This doesn't work!
175+
.AllowAnonymousToFolder("/Public").AuthorizePage("/Public/Private")
176+
```
177+
178+
Requiring authorization on the Private page fails. When both the <xref:Microsoft.AspNetCore.Mvc.Authorization.AllowAnonymousFilter> and <xref:Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter> are applied to the page, the <xref:Microsoft.AspNetCore.Mvc.Authorization.AllowAnonymousFilter> takes precedence and controls access.
179+
180+
## Additional resources
181+
182+
* <xref:razor-pages/razor-pages-conventions>
183+
* <xref:Microsoft.AspNetCore.Mvc.ApplicationModels.PageConventionCollection>

aspnetcore/security/authorization/introduction.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ Consult the documentation on [simple authorization](xref:security/authorization/
3030

3131
* <xref:fundamentals/minimal-apis/security>
3232
* <xref:blazor/security/index>
33+
* <xref:razor-pages/security/authorization/conventions>

aspnetcore/security/authorization/policies.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ Apply policies to Razor Pages by using the `[Authorize]` attribute with the poli
118118

119119
Policies can ***not*** be applied at the Razor Page handler level, they must be applied to the Page.
120120

121-
Policies can also be applied to Razor Pages by using an [authorization convention](xref:security/authorization/razor-pages-authorization).
121+
Policies can also be applied to Razor Pages by using an [authorization convention](xref:razor-pages/security/authorization/conventions).
122122

123123
## Apply policies to endpoints
124124

aspnetcore/security/authorization/policies/includes/policies5.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ Policies are applied to Razor Pages by using the `[Authorize]` attribute with th
108108

109109
Policies can ***not*** be applied at the Razor Page handler level, they must be applied to the Page.
110110

111-
Policies can be applied to Razor Pages by using an [authorization convention](xref:security/authorization/razor-pages-authorization).
111+
Policies can be applied to Razor Pages by using an [authorization convention](xref:razor-pages/security/authorization/conventions).
112112

113113
<a name="requirements"></a>
114114

0 commit comments

Comments
 (0)