Skip to content

Commit 2e34b74

Browse files
committed
Demo how to capture the user
1 parent 4afd671 commit 2e34b74

File tree

2 files changed

+81
-5
lines changed

2 files changed

+81
-5
lines changed

BlazorServerCaptureUser/Pages/Index.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
@page "/"
2-
2+
@inject UserService UserService
33
<PageTitle>Index</PageTitle>
44

5-
<h1>Hello, world!</h1>
5+
<h1>Hello, @(UserService.GetUser().Identity.Name ?? "world!")</h1>
66

77
Welcome to your new app.
88

BlazorServerCaptureUser/Program.cs

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
using BlazorServerCaptureUser.Areas.Identity;
22
using BlazorServerCaptureUser.Data;
3-
using Microsoft.AspNetCore.Components;
43
using Microsoft.AspNetCore.Components.Authorization;
5-
using Microsoft.AspNetCore.Components.Web;
4+
using Microsoft.AspNetCore.Components.Server.Circuits;
65
using Microsoft.AspNetCore.Identity;
7-
using Microsoft.AspNetCore.Identity.UI;
86
using Microsoft.EntityFrameworkCore;
7+
using Microsoft.Extensions.DependencyInjection.Extensions;
8+
using System.Security.Claims;
99

1010
var builder = WebApplication.CreateBuilder(args);
1111

@@ -21,6 +21,9 @@
2121
builder.Services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
2222
builder.Services.AddSingleton<WeatherForecastService>();
2323

24+
builder.Services.AddScoped<UserService>();
25+
builder.Services.TryAddEnumerable(ServiceDescriptor.Scoped<CircuitHandler, UserCircuitHandler>());
26+
2427
var app = builder.Build();
2528

2629
// Configure the HTTP request pipeline.
@@ -48,3 +51,76 @@
4851
app.MapFallbackToPage("/_Host");
4952

5053
app.Run();
54+
55+
public class UserService
56+
{
57+
private ClaimsPrincipal _currentUser = new ClaimsPrincipal(new ClaimsIdentity());
58+
59+
public ClaimsPrincipal GetUser()
60+
{
61+
return _currentUser;
62+
}
63+
64+
internal void SetUser(ClaimsPrincipal user)
65+
{
66+
// This might be called more than once
67+
if (_currentUser != user)
68+
{
69+
_currentUser = user;
70+
}
71+
}
72+
}
73+
74+
internal sealed class UserCircuitHandler : CircuitHandler, IDisposable
75+
{
76+
private readonly AuthenticationStateProvider _authenticationStateProvider;
77+
private readonly UserService _userService;
78+
79+
public UserCircuitHandler(
80+
AuthenticationStateProvider authenticationStateProvider,
81+
UserService userService)
82+
{
83+
_authenticationStateProvider = authenticationStateProvider;
84+
_userService = userService;
85+
}
86+
87+
public void Dispose()
88+
{
89+
_authenticationStateProvider.AuthenticationStateChanged -= AuthenticationChanged;
90+
}
91+
92+
// This and the method below are only needed if you want to update the user after the app has re-connected.
93+
public override Task OnCircuitOpenedAsync(Circuit circuit, CancellationToken cancellationToken)
94+
{
95+
// If you want to update the service, then you can attach an event handler as follows
96+
_authenticationStateProvider.AuthenticationStateChanged += AuthenticationChanged;
97+
return base.OnCircuitOpenedAsync(circuit, cancellationToken);
98+
}
99+
100+
private void AuthenticationChanged(Task<AuthenticationState> task)
101+
{
102+
_ = UpdateAuthentication(task);
103+
104+
async Task UpdateAuthentication(Task<AuthenticationState> task)
105+
{
106+
try
107+
{
108+
var state = await task;
109+
_userService.SetUser(state.User);
110+
}
111+
catch
112+
{
113+
// Swallow all exceptions here since there is no way to report them
114+
// (and if they come from the task, they'll be reported somewhere else).
115+
}
116+
}
117+
}
118+
119+
public override async Task OnConnectionUpAsync(Circuit circuit, CancellationToken cancellationToken)
120+
{
121+
// This gets called every time the circuit reconnects, setting the user for the lifetime of the connection.
122+
// Unless you implement updates.
123+
var state = await _authenticationStateProvider.GetAuthenticationStateAsync();
124+
_userService.SetUser(state.User);
125+
}
126+
}

0 commit comments

Comments
 (0)