Skip to content

Commit

Permalink
🐛 fix: Fix BlazorCurrentPrincipalAccessor in BlazorWebAssembly (#728)
Browse files Browse the repository at this point in the history
* 🐛 fix: Fix BlazorCurrentPrincipalAccessor in BlazorWebAssembly

* test: Adjust unit testing
  • Loading branch information
wzh425 authored Aug 28, 2024
1 parent 53d34c9 commit b757ee5
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ namespace Masa.Contrib.Authentication.Identity.BlazorWebAssembly;

public class BlazorCurrentPrincipalAccessor : ICurrentPrincipalAccessor
{
readonly AuthenticationStateProvider _authenticationStateProvider;
protected MasaComponentsClaimsCache ClaimsCache { get; }

public BlazorCurrentPrincipalAccessor(AuthenticationStateProvider authenticationStateProvider)
public BlazorCurrentPrincipalAccessor(IClientScopeServiceProviderAccessor clientScopeServiceProviderAccessor)
{
_authenticationStateProvider = authenticationStateProvider;
ClaimsCache = clientScopeServiceProviderAccessor.ServiceProvider.GetRequiredService<MasaComponentsClaimsCache>();
}

public ClaimsPrincipal? GetCurrentPrincipal()
{
return _authenticationStateProvider.GetAuthenticationStateAsync().Result.User;
return ClaimsCache.Principal;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Authentication.Identity.BlazorWebAssembly;

public class ComponentsClientScopeServiceProviderAccessor : IClientScopeServiceProviderAccessor
{
public IServiceProvider ServiceProvider { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Authentication.Identity.BlazorWebAssembly;

public class MasaComponentsClaimsCache : IScopedDependency
{
public ClaimsPrincipal Principal { get; private set; }
private readonly AuthenticationStateProvider _authenticationStateProvider;

public MasaComponentsClaimsCache(
IClientScopeServiceProviderAccessor serviceProviderAccessor)
{
_authenticationStateProvider = serviceProviderAccessor.ServiceProvider.GetService<AuthenticationStateProvider>();
if (_authenticationStateProvider != null)
{
_authenticationStateProvider.AuthenticationStateChanged += async (task) =>
{
Principal = (await task).User;
};
}
}

public virtual async Task InitializeAsync()
{
if (_authenticationStateProvider != null)
{
var authenticationState = await _authenticationStateProvider.GetAuthenticationStateAsync();
Principal = authenticationState.User;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Copyright (c) MASA Stack All rights reserved.
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

// ReSharper disable once CheckNamespace

namespace Microsoft.Extensions.DependencyInjection;

public static class ServiceCollectionExtensions
Expand Down Expand Up @@ -31,7 +32,17 @@ public static IServiceCollection AddMasaIdentity(
private static IServiceCollection AddMasaIdentityCore(IServiceCollection services)
{
services.AddAuthorizationCore();
services.TryAddScoped<MasaComponentsClaimsCache>();
services.TryAddSingleton<IClientScopeServiceProviderAccessor, ComponentsClientScopeServiceProviderAccessor>();
services.TryAddScoped<ICurrentPrincipalAccessor, BlazorCurrentPrincipalAccessor>();
return services;
}

public static async Task InitializeApplicationAsync(
[NotNull] this IServiceProvider serviceProvider)
{
((ComponentsClientScopeServiceProviderAccessor)serviceProvider
.GetRequiredService<IClientScopeServiceProviderAccessor>()).ServiceProvider = serviceProvider;
await serviceProvider.GetRequiredService<IClientScopeServiceProviderAccessor>().ServiceProvider.GetRequiredService<MasaComponentsClaimsCache>().InitializeAsync();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

global using Masa.Contrib.Authentication.Identity;
global using Masa.Contrib.Authentication.Identity.BlazorWebAssembly;
global using Masa.Contrib.Authentication.Identity.Core;
global using Microsoft.AspNetCore.Components.Authorization;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.DependencyInjection.Extensions;
global using System.Diagnostics.CodeAnalysis;
global using System.Security.Claims;
global using System.Text.Json;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Authentication.Identity.Core;

public interface IClientScopeServiceProviderAccessor
{
IServiceProvider ServiceProvider { get; }
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) MASA Stack All rights reserved.
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Authentication.Identity;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) MASA Stack All rights reserved.
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Authentication.Identity.BlazorWebAssembly.Tests;
Expand All @@ -21,7 +21,7 @@ public void TestMasaIdentity()
}

[TestMethod]
public void TestMasaIdentity2()
public async Task TestMasaIdentity2Async()
{
var services = new ServiceCollection();
var claimsPrincipal = new ClaimsPrincipal(new List<ClaimsIdentity>()
Expand All @@ -44,14 +44,17 @@ public void TestMasaIdentity2()
option.UserId = "sub";
});

var serviceProvider = services.BuildServiceProvider();
await serviceProvider.InitializeApplicationAsync();

Assert.IsTrue(services.Any<ICurrentPrincipalAccessor, BlazorCurrentPrincipalAccessor>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IUserSetter>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IUserContext>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IMultiTenantUserContext>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IMultiEnvironmentUserContext>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IIsolatedUserContext>(ServiceLifetime.Scoped));

var serviceProvider = services.BuildServiceProvider();

var userContext = serviceProvider.GetService<IUserContext>();
Assert.IsNotNull(userContext);
Assert.AreEqual("1", userContext.UserId);
Expand All @@ -63,7 +66,7 @@ public void TestMasaIdentity2()
}

[TestMethod]
public void TestIdentityByYaml()
public async Task TestIdentityByYamlAsync()
{
var services = new ServiceCollection();
services.AddMasaIdentity(string.Empty);
Expand Down Expand Up @@ -95,6 +98,7 @@ public void TestIdentityByYaml()

services.AddScoped(_ => authenticationStateProvider.Object);
serviceProvider = services.BuildServiceProvider();
await serviceProvider.InitializeApplicationAsync();

var userContext = serviceProvider.GetService<IUserContext>();
Assert.IsNotNull(userContext);
Expand All @@ -108,7 +112,7 @@ public void TestIdentityByYaml()
}

[TestMethod]
public void TestIdentityByYamlAndCustomOptions()
public async Task TestIdentityByYamlAndCustomOptionsAsync()
{
var services = new ServiceCollection();
services.AddMasaIdentity(string.Empty, option =>
Expand Down Expand Up @@ -143,6 +147,7 @@ public void TestIdentityByYamlAndCustomOptions()

services.AddScoped(_ => authenticationStateProvider.Object);
serviceProvider = services.BuildServiceProvider();
await serviceProvider.InitializeApplicationAsync();

var userContext = serviceProvider.GetService<IUserContext>();
Assert.IsNotNull(userContext);
Expand Down

0 comments on commit b757ee5

Please sign in to comment.