Skip to content

Commit e64b8a9

Browse files
authored
[Fixes #17014] Add an auth-enabled template for Blazor WASM projects (#18354)
* [Fixes #17014] Add an auth-enabled template for Blazor WASM projects * The template enables auth using cookies. * Includes a UserController to return the user claims/data to the user * Includes an IdentityAuthenticationStateProvider that fetches the claims data from the application. * It requires a hosted project.
1 parent 4ab5fe6 commit e64b8a9

34 files changed

+2256
-11
lines changed

eng/Versions.props

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@
204204
<SystemThreadingTasksExtensionsPackageVersion>4.5.2</SystemThreadingTasksExtensionsPackageVersion>
205205
<!-- Packages developed by @aspnet, but manually updated as necessary. -->
206206
<LibuvPackageVersion>1.10.0</LibuvPackageVersion>
207+
<MicrosoftAspNetCoreIdentityUIPackageVersion>3.1.0</MicrosoftAspNetCoreIdentityUIPackageVersion>
208+
<MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion>3.1.0</MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion>
209+
<MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>3.1.0</MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>
210+
<MicrosoftAspNetCoreComponentsAuthorizationPackageVersion>3.1.0</MicrosoftAspNetCoreComponentsAuthorizationPackageVersion>
207211
<MicrosoftAspNetWebApiClientPackageVersion>5.2.6</MicrosoftAspNetWebApiClientPackageVersion>
208212
<!-- Partner teams -->
209213
<MicrosoftAzureKeyVaultPackageVersion>2.3.2</MicrosoftAzureKeyVaultPackageVersion>

src/ProjectTemplates/BlazorWasm.ProjectTemplates/BlazorWasm-CSharp.Client.csproj.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="${MicrosoftAspNetCoreBlazorBuildPackageVersion}" PrivateAssets="all" />
1111
<PackageReference Include="Microsoft.AspNetCore.Blazor.DevServer" Version="${MicrosoftAspNetCoreBlazorDevServerPackageVersion}" PrivateAssets="all" />
1212
<PackageReference Include="Microsoft.AspNetCore.Blazor.HttpClient" Version="${MicrosoftAspNetCoreBlazorHttpClientPackageVersion}" />
13+
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="${MicrosoftAspNetCoreComponentsAuthorizationPackageVersion}" Condition="'$(IndividualLocalAuth)' == 'true'" />
1314
</ItemGroup>
1415
<!--#if Hosted -->
1516
<ItemGroup>

src/ProjectTemplates/BlazorWasm.ProjectTemplates/BlazorWasm-CSharp.Server.csproj.in

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,21 @@
1313
<ProjectReference Include="..\Shared\BlazorWasm-CSharp.Shared.csproj" />
1414
</ItemGroup>
1515

16+
<!--#if (IndividualLocalAuth && !UseLocalDB) -->
17+
<ItemGroup>
18+
<None Update="app.db" CopyToOutputDirectory="PreserveNewest" ExcludeFromSingleFile="true" />
19+
</ItemGroup>
20+
21+
<!--#endif -->
22+
<!--#if (IndividualLocalAuth) -->
23+
<ItemGroup>
24+
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="${MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion}" />
25+
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="${MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion}" />
26+
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="${MicrosoftAspNetCoreIdentityUIPackageVersion}" />
27+
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="${MicrosoftEntityFrameworkCoreSqlServerPackageVersion}" Condition="'$(UseLocalDB)' == 'True'" />
28+
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="${MicrosoftEntityFrameworkCoreSqlitePackageVersion}" Condition="'$(UseLocalDB)' != 'True'" />
29+
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="${MicrosoftEntityFrameworkCoreToolsPackageVersion}" />
30+
</ItemGroup>
31+
32+
<!--#endif -->
1633
</Project>

src/ProjectTemplates/BlazorWasm.ProjectTemplates/Microsoft.AspNetCore.Blazor.Templates.csproj

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@
2020
MicrosoftAspNetCoreBlazorBuildPackageVersion=$(MicrosoftAspNetCoreBlazorBuildPackageVersion);
2121
MicrosoftAspNetCoreBlazorDevServerPackageVersion=$(MicrosoftAspNetCoreBlazorDevServerPackageVersion);
2222
MicrosoftAspNetCoreBlazorHttpClientPackageVersion=$(MicrosoftAspNetCoreBlazorHttpClientPackageVersion);
23-
MonoWebAssemblyInteropPackageVersion=$(MonoWebAssemblyInteropPackageVersion);
24-
MicrosoftEntityFrameworkCoreSqlServerPackageVersion=$(MicrosoftEntityFrameworkCoreSqlServerPackageVersion);
2523
MicrosoftAspNetCoreBlazorServerPackageVersion=$(MicrosoftAspNetCoreBlazorServerPackageVersion);
24+
MicrosoftAspNetCoreComponentsAuthorizationPackageVersion=$(MicrosoftAspNetCoreComponentsAuthorizationPackageVersion);
25+
MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion=$(MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion);
26+
MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion=$(MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion);
27+
MicrosoftAspNetCoreIdentityUIPackageVersion=$(MicrosoftAspNetCoreIdentityUIPackageVersion);
28+
MicrosoftEntityFrameworkCoreSqlServerPackageVersion=$(MicrosoftEntityFrameworkCoreSqlServerPackageVersion);
29+
MicrosoftEntityFrameworkCoreSqlitePackageVersion=$(MicrosoftEntityFrameworkCoreSqlitePackageVersion);
30+
MicrosoftEntityFrameworkCoreToolsPackageVersion=$(MicrosoftEntityFrameworkCoreToolsPackageVersion);
31+
MonoWebAssemblyInteropPackageVersion=$(MonoWebAssemblyInteropPackageVersion);
2632
</GeneratedContentProperties>
2733
</PropertyGroup>
2834

src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/dotnetcli.host.json

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,31 @@
55
"longName": "no-restore",
66
"shortName": ""
77
},
8-
"Hosted": {
9-
"longName": "hosted"
10-
},
8+
"Hosted": {
9+
"longName": "hosted"
10+
},
1111
"Framework": {
1212
"longName": "framework"
13+
},
14+
"UseLocalDB": {
15+
"longName": "use-local-db"
16+
},
17+
"HttpPort": {
18+
"isHidden": true
19+
},
20+
"HttpsPort": {
21+
"isHidden": true
22+
},
23+
"ExcludeLaunchSettings": {
24+
"longName": "exclude-launch-settings",
25+
"shortName": ""
26+
},
27+
"UserSecretsId": {
28+
"isHidden": true
29+
},
30+
"NoHttps": {
31+
"longName": "no-https",
32+
"shortName": ""
1333
}
1434
}
15-
}
35+
}

src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/template.json

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,82 @@
7474
"exclude": [
7575
"*.sln"
7676
]
77+
},
78+
{
79+
"condition": "(!IndividualLocalAuth || UseLocalDB)",
80+
"exclude": [
81+
"Server/app.db"
82+
]
83+
},
84+
{
85+
"condition": "(!IndividualLocalAuth)",
86+
"exclude": [
87+
"Server/Data/SqlLite/**",
88+
"Server/Data/SqlServer/**",
89+
"Server/Data/ApplicationDbContext.cs",
90+
"Server/Areas/**"
91+
]
92+
},
93+
{
94+
"condition": "(IndividualLocalAuth && UseLocalDB)",
95+
"rename": {
96+
"Server/Data/SqlServer/": "Server/Data/Migrations/"
97+
},
98+
"exclude": [
99+
"Server/Data/SqlLite/**"
100+
]
101+
},
102+
{
103+
"condition": "(IndividualLocalAuth && !UseLocalDB)",
104+
"rename": {
105+
"Server/Data/SqlLite/": "Server/Data/Migrations/"
106+
},
107+
"exclude": [
108+
"Server/Data/SqlServer/**"
109+
]
110+
},
111+
{
112+
"condition": "(NoAuth && Hosted)",
113+
"rename": {
114+
"Client/Shared/MainLayout.NoAuth.razor": "Client/Shared/MainLayout.razor"
115+
},
116+
"exclude": [
117+
"Client/Shared/LoginDisplay.*.razor",
118+
"Client/Shared/MainLayout.Auth.razor"
119+
]
120+
},
121+
{
122+
"condition": "(!Hosted)",
123+
"rename": {
124+
"Client/Shared/MainLayout.NoAuth.razor": "Shared/MainLayout.razor"
125+
},
126+
"exclude": [
127+
"Client/Shared/LoginDisplay.*.razor",
128+
"Client/Shared/MainLayout.Auth.razor"
129+
]
130+
},
131+
{
132+
"condition": "(!NoAuth && Hosted)",
133+
"rename": {
134+
"Client/Shared/MainLayout.Auth.razor": "Client/Shared/MainLayout.razor"
135+
},
136+
"exclude": [
137+
"Client/Shared/MainLayout.NoAuth.razor"
138+
]
139+
},
140+
{
141+
"condition": "(IndividualLocalAuth)",
142+
"rename": {
143+
"Client/Shared/LoginDisplay.IndividualLocalAuth.razor": "Client/Shared/LoginDisplay.razor"
144+
}
145+
},
146+
{
147+
"condition": "(NoAuth)",
148+
"exclude": [
149+
"Client/Services/HostAuthenticationStateProvider.cs",
150+
"Server/Controllers/UserController.cs",
151+
"Shared/Authorization/*"
152+
]
77153
}
78154
]
79155
}
@@ -107,6 +183,111 @@
107183
"datatype": "bool",
108184
"defaultValue": "false",
109185
"description": "If specified, includes an ASP.NET Core host for the Blazor app."
186+
},
187+
"auth": {
188+
"type": "parameter",
189+
"datatype": "choice",
190+
"choices": [
191+
{
192+
"choice": "None",
193+
"description": "No authentication"
194+
},
195+
{
196+
"choice": "Individual",
197+
"description": "Individual authentication"
198+
}
199+
],
200+
"defaultValue": "None",
201+
"description": "The type of authentication to use"
202+
},
203+
"UserSecretsId": {
204+
"type": "parameter",
205+
"datatype": "string",
206+
"replaces": "aspnet-BlazorServerWeb-CSharp-53bc9b9d-9d6a-45d4-8429-2a2761773502",
207+
"defaultValue": "aspnet-BlazorServerWeb-CSharp-53bc9b9d-9d6a-45d4-8429-2a2761773502",
208+
"description": "The ID to use for secrets (use with OrgReadAccess or Individual auth)."
209+
},
210+
"ExcludeLaunchSettings": {
211+
"type": "parameter",
212+
"datatype": "bool",
213+
"defaultValue": "false",
214+
"description": "Whether to exclude launchSettings.json from the generated template."
215+
},
216+
"HttpPort": {
217+
"type": "parameter",
218+
"datatype": "integer",
219+
"description": "Port number to use for the HTTP endpoint in launchSettings.json."
220+
},
221+
"HttpPortGenerated": {
222+
"type": "generated",
223+
"generator": "port"
224+
},
225+
"HttpPortReplacer": {
226+
"type": "generated",
227+
"generator": "coalesce",
228+
"parameters": {
229+
"sourceVariableName": "HttpPort",
230+
"fallbackVariableName": "HttpPortGenerated"
231+
},
232+
"replaces": "8080"
233+
},
234+
"HttpsPort": {
235+
"type": "parameter",
236+
"datatype": "integer",
237+
"description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used)."
238+
},
239+
"HttpsPortGenerated": {
240+
"type": "generated",
241+
"generator": "port",
242+
"parameters": {
243+
"low": 44300,
244+
"high": 44399
245+
}
246+
},
247+
"HttpsPortReplacer": {
248+
"type": "generated",
249+
"generator": "coalesce",
250+
"parameters": {
251+
"sourceVariableName": "HttpsPort",
252+
"fallbackVariableName": "HttpsPortGenerated"
253+
},
254+
"replaces": "44300"
255+
},
256+
"IndividualLocalAuth": {
257+
"type": "computed",
258+
"value": "(auth == \"Individual\")"
259+
},
260+
"NoAuth": {
261+
"type": "computed",
262+
"value": "(!(IndividualAuth))"
263+
},
264+
"IndividualAuth": {
265+
"type": "computed",
266+
"value": "(IndividualLocalAuth)"
267+
},
268+
"RequiresHttps": {
269+
"type": "computed",
270+
"value": "(IndividualAuth || !NoHttps)"
271+
},
272+
"NoHttps": {
273+
"type": "parameter",
274+
"datatype": "bool",
275+
"defaultValue": "false",
276+
"description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth."
277+
},
278+
"UseLocalDB": {
279+
"type": "parameter",
280+
"datatype": "bool",
281+
"defaultValue": "false",
282+
"description": "Whether to use LocalDB instead of SQLite. This option only applies if --auth Individual or --auth IndividualB2C is specified."
283+
},
284+
"copyrightYear": {
285+
"type": "generated",
286+
"generator": "now",
287+
"replaces": "copyrightYear",
288+
"parameters": {
289+
"format": "yyyy"
290+
}
110291
}
111292
},
112293
"tags": {

src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/vs-2017.3.host.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,30 @@
1818
"additionalWizardParameters": {
1919
"$isMultiProjectTemplate$": "true"
2020
},
21+
"supportedAuthentications": [
22+
{
23+
"auth": "None",
24+
"authenticationType": "NoAuth",
25+
"allowUnsecured": true
26+
},
27+
{
28+
"auth": "Individual",
29+
"authenticationType": "IndividualAuth",
30+
"b2cAuthenticationOptions": "Local"
31+
}
32+
],
33+
"ports": [
34+
{
35+
"name": "HttpPort",
36+
"useHttps": false
37+
},
38+
{
39+
"name": "HttpsPort",
40+
"useHttps": true
41+
}
42+
],
43+
"excludeLaunchSettings": false,
44+
"disableHttpsSymbol": "NoHttps",
2145
"symbolInfo": [
2246
{
2347
"id": "Hosted",

src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/App.razor

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
<Router AppAssembly="@typeof(Program).Assembly">
1+
@*#if (NoAuth)
2+
<Router AppAssembly="@typeof(Program).Assembly">
23
<Found Context="routeData">
34
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
45
</Found>
@@ -8,3 +9,17 @@
89
</LayoutView>
910
</NotFound>
1011
</Router>
12+
#else
13+
<CascadingAuthenticationState>
14+
<Router AppAssembly="@typeof(Program).Assembly">
15+
<Found Context="routeData">
16+
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
17+
</Found>
18+
<NotFound>
19+
<LayoutView Layout="@typeof(MainLayout)">
20+
<p>Sorry, there's nothing at this address.</p>
21+
</LayoutView>
22+
</NotFound>
23+
</Router>
24+
</CascadingAuthenticationState>
25+
#endif*@

src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/Pages/FetchData.razor

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
@page "/fetchdata"
2+
@*#if (!NoAuth)
3+
@using Microsoft.AspNetCore.Authorization
4+
#endif*@
25
@*#if (Hosted)
36
@using BlazorWasm_CSharp.Shared
47
#endif*@
8+
@*#if (!NoAuth)
9+
@attribute [Authorize]
10+
#endif*@
511
@inject HttpClient Http
612

713
<h1>Weather forecast</h1>

0 commit comments

Comments
 (0)