Skip to content

Commit

Permalink
Refactored the use of ClaimsLite and ClaimsRecord into a single type
Browse files Browse the repository at this point in the history
  • Loading branch information
Erwinvandervalk committed Feb 4, 2025
1 parent 9039293 commit 7102def
Show file tree
Hide file tree
Showing 19 changed files with 105 additions and 58 deletions.
3 changes: 3 additions & 0 deletions bff/migrations/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<Import Project="../../samples.props" />
</Project>
4 changes: 2 additions & 2 deletions bff/migrations/UserSessionDb/UserSessionDb.csproj
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFrameworks>net9.0</TargetFrameworks>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" >
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
2 changes: 1 addition & 1 deletion bff/samples/Apis/Api.DPoP/Api.DPoP.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFrameworks>net9.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion bff/samples/Bff/Bff.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFrameworks>net9.0</TargetFrameworks>
<RootNamespace>Bff</RootNamespace>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
19 changes: 19 additions & 0 deletions bff/samples/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<!-- This line is needed because:
Aspire needs a single target framework
(until this is resolved: https://github.com/dotnet/aspire/issues/2962)
When you add <TargetFrameworks>net9.0</TargetFrameworks> then aspire thinks there are more than
one framework. But this causes a problem for the Directory.Packages.props file.
In the Directory.Packages.props where we check for $(TargetFramework) == 'net9.0',
which is ONLY set if you use <TargetFrameworks>net9.0</TargetFrameworks> in the csproj file, not
if you set <TargetFramework>.
Now normally it's not recommended to set both, however, since this is only for samples, AND
we do need this check, we're setting it here as well.
-->
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<Import Project="../../samples.props" />
</Project>
2 changes: 1 addition & 1 deletion bff/samples/Hosts.Tests/Hosts.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFrameworks>net9.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
Expand Down
41 changes: 41 additions & 0 deletions bff/src/Duende.Bff.Blazor.Client/ClaimRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Text.Json.Serialization;

namespace Duende.Bff;

/// <summary>
/// Serialization friendly claim.
///
/// Note, this is a copy of the ClaimRecord class from Duende.Bff, but since we can't create a reference to it, we need to copy it here.
/// We also can't link to it (as we do with the extensions) because the other ClaimRecord class is public and this one is intentionally internal.
/// </summary>
internal class ClaimRecord()
{
/// <summary>
/// Serialization friendly claim
/// </summary>
/// <param name="type">The type</param>
/// <param name="value">The Value</param>
internal ClaimRecord(string type, object value) : this()
{
Type = type;
Value = value;
}

/// <summary>
/// The type
/// </summary>
[JsonPropertyName("type")]
public string Type { get; init; } = default!;

/// <summary>
/// The value
/// </summary>
[JsonPropertyName("value")]
public object Value { get; init; } = default!;

/// <summary>
/// The value type
/// </summary>
[JsonPropertyName("valueType")]
public string? ValueType { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
</PropertyGroup>

<ItemGroup>
<Compile Include="..\Duende.Bff\Shared\ClaimLite.cs" Link="Shared\ClaimLite.cs" />
<Compile Include="..\Duende.Bff\Shared\ClaimsLiteExtensions.cs" Link="Shared\ClaimsLiteExtensions.cs" />
<Compile Include="..\Duende.Bff\Shared\ClaimsPrincipalLite.cs" Link="Shared\ClaimsPrincipalLite.cs" />
<Compile Include="..\Duende.Bff\Shared\ClaimRecordExtensions.cs" Link="Shared\ClaimRecordExtensions.cs" />
<Compile Include="..\Duende.Bff\Shared\ClaimsPrincipalRecord.cs" Link="Shared\ClaimsPrincipalRecord.cs" />
</ItemGroup>

<ItemGroup>
Expand Down
3 changes: 0 additions & 3 deletions bff/src/Duende.Bff.Blazor.Client/Internals/GetUserService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ public async ValueTask<ClaimsPrincipal> GetUserAsync(bool useCache = true)
return _cachedUser;
}

// TODO - Consider using ClaimLite instead here
record ClaimRecord(string Type, object Value);

internal async Task<ClaimsPrincipal> FetchUser()
{
try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ internal class PersistentUserService(PersistentComponentState state, ILogger<Per
/// <inheritdoc />
public ClaimsPrincipal GetPersistedUser()
{
if (!state.TryTakeFromJson<ClaimsPrincipalLite>(nameof(ClaimsPrincipalLite), out var lite) || lite is null)
if (!state.TryTakeFromJson<ClaimsPrincipalRecord>(nameof(ClaimsPrincipalRecord), out var lite) || lite is null)
{
logger.LogDebug("Failed to load persisted user.");
return new ClaimsPrincipal(new ClaimsIdentity());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ private async Task OnPersistingAsync()
var authenticationState = await _authenticationStateTask;

var claims = authenticationState.User.Claims
.Select(c => new ClaimLite
.Select(c => new ClaimRecord
{
Type = c.Type,
Value = c.Value?.ToString() ?? string.Empty,
ValueType = c.ValueType == ClaimValueTypes.String ? null : c.ValueType
}).ToArray();

var principal = new ClaimsPrincipalLite
var principal = new ClaimsPrincipalRecord
{
AuthenticationType = authenticationState.User.Identity!.AuthenticationType,
NameClaimType = authenticationState.User.Identities.First().NameClaimType,
Expand All @@ -90,7 +90,7 @@ private async Task OnPersistingAsync()

_logger.LogDebug("Persisting Authentication State");

_state.PersistAsJson(nameof(ClaimsPrincipalLite), principal);
_state.PersistAsJson(nameof(ClaimsPrincipalRecord), principal);
}


Expand Down
16 changes: 1 addition & 15 deletions bff/src/Duende.Bff/EndpointServices/User/DefaultUserService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
Expand Down Expand Up @@ -134,20 +135,5 @@ protected virtual Task<IEnumerable<ClaimRecord>> GetManagementClaimsAsync(HttpCo

return Task.FromResult((IEnumerable<ClaimRecord>)claims);
}

/// <summary>
/// Serialization-friendly claim
/// </summary>
/// <param name="Type"></param>
/// <param name="Value"></param>
protected record ClaimRecord(string Type, object Value)
{
/// <summary></summary>
[JsonPropertyName("type")]
public string Type { get; init; } = Type;

/// <summary></summary>
[JsonPropertyName("value")]
public object Value { get; init; } = Value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ internal class AuthenticationTicketLite
/// <summary>
/// The user
/// </summary>
public ClaimsPrincipalLite User { get; set; } = default!;
public ClaimsPrincipalRecord User { get; set; } = default!;

/// <summary>
/// The items
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,41 @@
// Copyright (c) Duende Software. All rights reserved.
// See LICENSE in the project root for license information.

using System.Text.Json.Serialization;

namespace Duende.Bff;

/// <summary>
/// Serialization friendly claim
/// </summary>
internal class ClaimLite
public class ClaimRecord()
{
/// <summary>
///
/// </summary>
/// <param name="type"></param>
/// <param name="value"></param>
public ClaimRecord(string type, object value) : this()
{
Type = type;
Value = value;
}

/// <summary>
/// The type
/// </summary>
[JsonPropertyName("type")]
public string Type { get; init; } = default!;

/// <summary>
/// The value
/// </summary>
public string Value { get; init; } = default!;
[JsonPropertyName("value")]
public object Value { get; init; } = default!;

/// <summary>
/// The value type
/// </summary>
[JsonPropertyName("valueType")]
public string? ValueType { get; init; }
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
// Copyright (c) Duende Software. All rights reserved.
// See LICENSE in the project root for license information.

using System.Linq;
using System.Security.Claims;

namespace Duende.Bff;

internal static class ClaimsLiteExtensions
internal static class ClaimRecordExtensions
{
/// <summary>
/// Converts a ClaimsPrincipalLite to ClaimsPrincipal
/// </summary>
public static ClaimsPrincipal ToClaimsPrincipal(this ClaimsPrincipalLite principal)
public static ClaimsPrincipal ToClaimsPrincipal(this ClaimsPrincipalRecord principal)
{
var claims = principal.Claims.Select(x => new Claim(x.Type, x.Value, x.ValueType ?? ClaimValueTypes.String))
var claims = principal.Claims.Select(x => new Claim(x.Type, x.Value.ToString() ?? string.Empty, x.ValueType ?? ClaimValueTypes.String))
.ToArray();
var id = new ClaimsIdentity(claims, principal.AuthenticationType, principal.NameClaimType,
principal.RoleClaimType);
Expand All @@ -24,17 +23,17 @@ public static ClaimsPrincipal ToClaimsPrincipal(this ClaimsPrincipalLite princip
/// <summary>
/// Converts a ClaimsPrincipal to ClaimsPrincipalLite
/// </summary>
public static ClaimsPrincipalLite ToClaimsPrincipalLite(this ClaimsPrincipal principal)
public static ClaimsPrincipalRecord ToClaimsPrincipalLite(this ClaimsPrincipal principal)
{
var claims = principal.Claims.Select(
x => new ClaimLite
x => new ClaimRecord
{
Type = x.Type,
Value = x.Value,
ValueType = x.ValueType == ClaimValueTypes.String ? null : x.ValueType
}).ToArray();

return new ClaimsPrincipalLite
return new ClaimsPrincipalRecord
{
AuthenticationType = principal.Identity!.AuthenticationType,
NameClaimType = principal.Identities.First().NameClaimType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Duende.Bff;
/// <summary>
/// Serialization friendly ClaimsPrincipal
/// </summary>
internal class ClaimsPrincipalLite
internal class ClaimsPrincipalRecord
{
/// <summary>
/// The authentication type
Expand All @@ -26,5 +26,5 @@ internal class ClaimsPrincipalLite
/// <summary>
/// The claims
/// </summary>
public ClaimLite[] Claims { get; init; } = default!;
public ClaimRecord[] Claims { get; init; } = default!;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Security.Cryptography;
using System.Text.Json;
using System.Threading.Tasks;
using Duende.Bff.Tests.TestFramework;
using Duende.Bff.Tests.TestHosts;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
Expand Down Expand Up @@ -35,7 +36,7 @@ public DpopRemoteEndpointTests(ITestOutputHelper output) : base(output)
[Fact]
public async Task test_dpop()
{
var apiResult = await BffHost.BrowserClient.CallBffHostApi(
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
url: BffHost.Url("/api_client/test")
);

Check failure on line 42 in bff/test/Duende.Bff.Tests/Endpoints/DpopRemoteEndpointTests.cs

View workflow job for this annotation

GitHub Actions / Build

'TestBrowserClient.BffHostResponse' does not contain a definition for 'RequestHeaders' and no accessible extension method 'RequestHeaders' accepting a first argument of type 'TestBrowserClient.BffHostResponse' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 42 in bff/test/Duende.Bff.Tests/Endpoints/DpopRemoteEndpointTests.cs

View workflow job for this annotation

GitHub Actions / Build

'TestBrowserClient.BffHostResponse' does not contain a definition for 'RequestHeaders' and no accessible extension method 'RequestHeaders' accepting a first argument of type 'TestBrowserClient.BffHostResponse' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 42 in bff/test/Duende.Bff.Tests/Endpoints/DpopRemoteEndpointTests.cs

View workflow job for this annotation

GitHub Actions / Build

'TestBrowserClient.BffHostResponse' does not contain a definition for 'RequestHeaders' and no accessible extension method 'RequestHeaders' accepting a first argument of type 'TestBrowserClient.BffHostResponse' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 42 in bff/test/Duende.Bff.Tests/Endpoints/DpopRemoteEndpointTests.cs

View workflow job for this annotation

GitHub Actions / Build

'TestBrowserClient.BffHostResponse' does not contain a definition for 'RequestHeaders' and no accessible extension method 'RequestHeaders' accepting a first argument of type 'TestBrowserClient.BffHostResponse' could be found (are you missing a using directive or an assembly reference?)
Expand Down
7 changes: 1 addition & 6 deletions bff/test/Duende.Bff.Tests/Endpoints/RemoteEndpointTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@

using Duende.Bff.Tests.TestFramework;
using Duende.Bff.Tests.TestHosts;
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using Shouldly;
using Xunit;
using System.Text.Json;
using Xunit.Abstractions;

namespace Duende.Bff.Tests.Endpoints
Expand Down
9 changes: 0 additions & 9 deletions bff/test/Duende.Bff.Tests/TestFramework/Records.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,4 @@ public record JsonRecord(string Type, JsonElement Value)
[JsonPropertyName("value")]
public JsonElement Value { get; } = Value;
}

public record ClaimRecord(string Type, string Value)
{
[JsonPropertyName("type")]
public string Type { get; } = Type;

[JsonPropertyName("value")]
public string Value { get; } = Value;
}
}

0 comments on commit 7102def

Please sign in to comment.