Skip to content

Commit 7906488

Browse files
committed
Support all InteractivityPlatform choices
1 parent 8451997 commit 7906488

File tree

15 files changed

+317
-88
lines changed

15 files changed

+317
-88
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,6 @@
5656
}
5757
},
5858
"usageExamples": [
59-
"--use-wasm --auth Individual --use-local-db"
59+
"-int auto --auth individual --use-local-db"
6060
]
6161
}

src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/.template.config/ide.host.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
{
2424
"id": "auth",
2525
"isVisible": true,
26-
"defaultValue": "None",
2726
"persistenceScope": "templateGroup"
2827
},
2928
{

src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/.template.config/template.json

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,41 @@
117117
"BlazorWeb-CSharp/Components/Identity/**",
118118
"BlazorWeb-CSharp/Data/**",
119119
"BlazorWeb-CSharp/Identity/**",
120-
"BlazorWeb-CSharp/PersistingAuthenticationStateProvider.cs",
121120
"BlazorWeb-CSharp.Client/PersistentAuthenticationStateProvider.cs",
122121
"BlazorWeb-CSharp.Client/UserInfo.cs",
123122
"BlazorWeb-CSharp.Client/Pages/Auth.razor"
124123
]
125124
},
126125
{
127-
"condition": "(!IndividualLocalAuth || UseLocalDB)",
126+
"condition": "(!(IndividualLocalAuth && !UseLocalDB))",
128127
"exclude": [
129128
"BlazorWeb-CSharp/app.db"
130129
]
131130
},
131+
{
132+
"condition": "(!(IndividualLocalAuth && !UseWebAssembly))",
133+
"exclude": [
134+
"BlazorWeb-CSharp/Components/Pages/Auth.razor"
135+
]
136+
},
137+
{
138+
"condition": "(!(IndividualLocalAuth && UseServer && UseWebAssembly))",
139+
"exclude": [
140+
"BlazorWeb-CSharp/Identity/PersistingRevalidatingAuthenticationStateProvider.cs"
141+
]
142+
},
143+
{
144+
"condition": "(!(IndividualLocalAuth && UseServer && !UseWebAssembly))",
145+
"exclude": [
146+
"BlazorWeb-CSharp/Identity/IdentityRevalidatingAuthenticationStateProvider.cs"
147+
]
148+
},
149+
{
150+
"condition": "(!(IndividualLocalAuth && !UseServer && UseWebAssembly))",
151+
"exclude": [
152+
"BlazorWeb-CSharp/Identity/PersistingServerAuthenticationStateProvider.cs"
153+
]
154+
},
132155
{
133156
"condition": "(IndividualLocalAuth && UseLocalDB && UseWebAssembly)",
134157
"rename": {

src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp.Client/Pages/Auth.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@page "/auth"
22

3-
@using Microsoft.AspNetCore.Authorization;
3+
@using Microsoft.AspNetCore.Authorization
44

55
@attribute [Authorize]
66
@*#if (UseServer && !InteractiveAtRoot)
@@ -14,5 +14,5 @@
1414
<h1>You are authenticated</h1>
1515

1616
<AuthorizeView>
17-
<p>Hello @context.User.Identity?.Name!</p>
17+
Hello @context.User.Identity?.Name!
1818
</AuthorizeView>

src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp.Client/PersistentAuthenticationStateProvider.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ public class PersistentAuthenticationStateProvider(PersistentComponentState pers
1111

1212
public override Task<AuthenticationState> GetAuthenticationStateAsync()
1313
{
14-
// REVIEW: Is TryTakeFromJson correctly annotated? "|| userInfo is null" should not be necessary.
1514
if (!persistentState.TryTakeFromJson<UserInfo>(nameof(UserInfo), out var userInfo) || userInfo is null)
1615
{
1716
return _unauthenticatedTask;

src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Layout/NavMenu.razor

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,13 @@
3131
<span class="bi bi-list-nested" aria-hidden="true"></span> Weather
3232
</NavLink>
3333
</div>
34-
@*#if (IndividualLocalAuth && UseWebAssembly)
34+
@*#if (IndividualLocalAuth)
3535
3636
<div class="nav-item px-3">
3737
<NavLink class="nav-link" href="auth">
3838
<span class="bi bi-lock" aria-hidden="true"></span> Auth Required
3939
</NavLink>
4040
</div>
41-
##endif*@
42-
@*#if (IndividualLocalAuth)
4341
4442
<AuthorizeView>
4543
<Authorized>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@page "/auth"
2+
3+
@using Microsoft.AspNetCore.Authorization
4+
5+
@attribute [Authorize]
6+
7+
<PageTitle>Auth</PageTitle>
8+
9+
<h1>You are authenticated</h1>
10+
11+
<AuthorizeView>
12+
Hello @context.User.Identity?.Name!
13+
</AuthorizeView>

src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Data/ApplicationDbContext.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@
33

44
namespace BlazorWeb_CSharp.Data;
55

6-
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
6+
public class ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : IdentityDbContext<ApplicationUser>(options)
77
{
8-
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
9-
: base(options)
10-
{
11-
}
128
}

src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Identity/Extensions/IdentityComponentsEndpointRouteBuilderExtensions.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ public static IEndpointConventionBuilder MapAdditionalIdentityEndpoints(this IEn
1818
{
1919
ArgumentNullException.ThrowIfNull(endpoints);
2020

21-
var loggerFactory = endpoints.ServiceProvider.GetRequiredService<ILoggerFactory>();
22-
var logger = loggerFactory.CreateLogger("IdentityUI");
2321
var accountGroup = endpoints.MapGroup("/Account");
2422

2523
accountGroup.MapPost("/PerformExternalLogin", (
@@ -60,6 +58,9 @@ public static IEndpointConventionBuilder MapAdditionalIdentityEndpoints(this IEn
6058
return Results.Challenge(properties, [provider]);
6159
});
6260

61+
var loggerFactory = endpoints.ServiceProvider.GetRequiredService<ILoggerFactory>();
62+
var downloadLogger = loggerFactory.CreateLogger("DownloadPersonalData");
63+
6364
manageGroup.MapPost("/DownloadPersonalData", async (
6465
HttpContext context,
6566
[FromServices] UserManager<ApplicationUser> userManager,
@@ -72,7 +73,7 @@ public static IEndpointConventionBuilder MapAdditionalIdentityEndpoints(this IEn
7273
}
7374

7475
var userId = await userManager.GetUserIdAsync(user);
75-
logger.LogInformation("User with ID '{UserId}' asked for their personal data.", userId);
76+
downloadLogger.LogInformation("User with ID '{UserId}' asked for their personal data.", userId);
7677

7778
// Only include personal data for download
7879
var personalData = new Dictionary<string, string>();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System.Security.Claims;
2+
using Microsoft.AspNetCore.Components.Authorization;
3+
using Microsoft.AspNetCore.Components.Server;
4+
using Microsoft.AspNetCore.Identity;
5+
using Microsoft.Extensions.Options;
6+
using BlazorWeb_CSharp.Data;
7+
8+
namespace BlazorWeb_CSharp.Identity;
9+
10+
public class IdentityRevalidatingAuthenticationStateProvider : RevalidatingServerAuthenticationStateProvider
11+
{
12+
private readonly IServiceScopeFactory _scopeFactory;
13+
private readonly IdentityOptions _options;
14+
15+
public IdentityRevalidatingAuthenticationStateProvider(
16+
ILoggerFactory loggerFactory,
17+
IServiceScopeFactory scopeFactory,
18+
IOptions<IdentityOptions> optionsAccessor)
19+
: base(loggerFactory)
20+
{
21+
_scopeFactory = scopeFactory;
22+
_options = optionsAccessor.Value;
23+
}
24+
25+
protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(30);
26+
27+
protected override async Task<bool> ValidateAuthenticationStateAsync(
28+
AuthenticationState authenticationState, CancellationToken cancellationToken)
29+
{
30+
// Get the user manager from a new scope to ensure it fetches fresh data
31+
await using var scope = _scopeFactory.CreateAsyncScope();
32+
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
33+
return await ValidateSecurityStampAsync(userManager, authenticationState.User);
34+
}
35+
36+
private async Task<bool> ValidateSecurityStampAsync(UserManager<ApplicationUser> userManager, ClaimsPrincipal principal)
37+
{
38+
var user = await userManager.GetUserAsync(principal);
39+
if (user == null)
40+
{
41+
return false;
42+
}
43+
else if (!userManager.SupportsUserSecurityStamp)
44+
{
45+
return true;
46+
}
47+
else
48+
{
49+
var principalStamp = principal.FindFirstValue(_options.ClaimsIdentity.SecurityStampClaimType);
50+
var userStamp = await userManager.GetSecurityStampAsync(user);
51+
return principalStamp == userStamp;
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)