Skip to content

Commit ee982a2

Browse files
Initialize the authentication state provider during static prerendering
1 parent 5a84240 commit ee982a2

File tree

6 files changed

+65
-42
lines changed

6 files changed

+65
-42
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Threading.Tasks;
5+
6+
namespace Microsoft.AspNetCore.Components
7+
{
8+
/// <summary>
9+
/// An interface implemented by <see cref="AuthenticationStateProvider"/> classes that can receive authentication
10+
/// state information from the host environment.
11+
/// </summary>
12+
public interface IHostEnvironmentAuthenticationStateProvider
13+
{
14+
/// <summary>
15+
/// Supplies updated authentication state data to the <see cref="AuthenticationStateProvider"/>.
16+
/// </summary>
17+
/// <param name="authenticationStateTask">A task that resolves with the updated <see cref="AuthenticationState"/>.</param>
18+
void SetAuthenticationState(Task<AuthenticationState> authenticationStateTask);
19+
}
20+
}

src/Components/Server/src/Circuits/DefaultCircuitFactory.cs

+7-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
using Microsoft.Extensions.DependencyInjection;
1515
using Microsoft.Extensions.Logging;
1616
using Microsoft.JSInterop;
17+
using System.Threading.Tasks;
1718

1819
namespace Microsoft.AspNetCore.Components.Server.Circuits
1920
{
@@ -50,9 +51,12 @@ public override CircuitHost CreateCircuitHost(
5051
jsRuntime.Initialize(client);
5152
componentContext.Initialize(client);
5253

53-
// You can replace the AuthenticationStateProvider with a custom one, but in that case initialization is up to you
54-
var authenticationStateProvider = scope.ServiceProvider.GetService<AuthenticationStateProvider>();
55-
(authenticationStateProvider as FixedAuthenticationStateProvider)?.Initialize(httpContext.User);
54+
var authenticationStateProvider = scope.ServiceProvider.GetService<AuthenticationStateProvider>() as IHostEnvironmentAuthenticationStateProvider;
55+
if (authenticationStateProvider != null)
56+
{
57+
var authenticationState = new AuthenticationState(httpContext.User); // TODO: Get this from the hub connection context instead
58+
authenticationStateProvider.SetAuthenticationState(Task.FromResult(authenticationState));
59+
}
5660

5761
var uriHelper = (RemoteUriHelper)scope.ServiceProvider.GetRequiredService<IUriHelper>();
5862
var navigationInterception = (RemoteNavigationInterception)scope.ServiceProvider.GetRequiredService<INavigationInterception>();

src/Components/Server/src/Circuits/FixedAuthenticationStateProvider.cs

-33
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Threading.Tasks;
6+
7+
namespace Microsoft.AspNetCore.Components.Server.Circuits
8+
{
9+
/// <summary>
10+
/// An <see cref="AuthenticationStateProvider"/> intended for use in server-side Blazor.
11+
/// </summary>
12+
internal class ServerAuthenticationStateProvider : AuthenticationStateProvider, IHostEnvironmentAuthenticationStateProvider
13+
{
14+
private Task<AuthenticationState> _authenticationStateTask;
15+
16+
public override Task<AuthenticationState> GetAuthenticationStateAsync()
17+
=> _authenticationStateTask
18+
?? throw new InvalidOperationException($"{nameof(GetAuthenticationStateAsync)} was called before {nameof(SetAuthenticationState)}.");
19+
20+
public void SetAuthenticationState(Task<AuthenticationState> authenticationStateTask)
21+
{
22+
_authenticationStateTask = authenticationStateTask ?? throw new ArgumentNullException(nameof(authenticationStateTask));
23+
NotifyAuthenticationStateChanged(_authenticationStateTask);
24+
}
25+
}
26+
}

src/Components/Server/src/DependencyInjection/ComponentServiceCollectionExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public static IServerSideBlazorBuilder AddServerSideBlazor(this IServiceCollecti
7676
services.AddScoped<IJSRuntime, RemoteJSRuntime>();
7777
services.AddScoped<INavigationInterception, RemoteNavigationInterception>();
7878
services.AddScoped<IComponentContext, RemoteComponentContext>();
79-
services.AddScoped<AuthenticationStateProvider, FixedAuthenticationStateProvider>();
79+
services.AddScoped<AuthenticationStateProvider, ServerAuthenticationStateProvider>();
8080

8181
services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<CircuitOptions>, CircuitOptionsJSInteropDetailedErrorsConfiguration>());
8282

src/Mvc/Mvc.ViewFeatures/src/RazorComponents/StaticComponentRenderer.cs

+11-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public async Task<IEnumerable<string>> PrerenderComponentAsync(
3030
HttpContext httpContext,
3131
Type componentType)
3232
{
33-
InitializeUriHelper(httpContext);
33+
InitializeStandardComponentServices(httpContext);
3434
var loggerFactory = (ILoggerFactory)httpContext.RequestServices.GetService(typeof (ILoggerFactory));
3535
using (var htmlRenderer = new HtmlRenderer(httpContext.RequestServices, loggerFactory, _encoder.Encode))
3636
{
@@ -62,15 +62,21 @@ public async Task<IEnumerable<string>> PrerenderComponentAsync(
6262
}
6363
}
6464

65-
private void InitializeUriHelper(HttpContext httpContext)
65+
private void InitializeStandardComponentServices(HttpContext httpContext)
6666
{
67-
// We don't know here if we are dealing with the default HttpUriHelper registered
68-
// by MVC or with the RemoteUriHelper registered by AddComponents.
6967
// This might not be the first component in the request we are rendering, so
70-
// we need to check if we already initialized the uri helper in this request.
68+
// we need to check if we already initialized the services in this request.
7169
if (!_initialized)
7270
{
7371
_initialized = true;
72+
73+
var authenticationStateProvider = httpContext.RequestServices.GetService<AuthenticationStateProvider>() as IHostEnvironmentAuthenticationStateProvider;
74+
if (authenticationStateProvider != null)
75+
{
76+
var authenticationState = new AuthenticationState(httpContext.User);
77+
authenticationStateProvider.SetAuthenticationState(Task.FromResult(authenticationState));
78+
}
79+
7480
var helper = (UriHelperBase)httpContext.RequestServices.GetRequiredService<IUriHelper>();
7581
helper.InitializeState(GetFullUri(httpContext.Request), GetContextBaseUri(httpContext.Request));
7682
}

0 commit comments

Comments
 (0)