Skip to content

Commit d6352e3

Browse files
committed
Fix Orleans identity core claim helpers
1 parent 0ca3d3d commit d6352e3

4 files changed

Lines changed: 45 additions & 10 deletions

File tree

ManagedCode.Orleans.Identity.Core/Extensions/OrleansExtensions.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
using System;
21
using System.Security.Claims;
32
using ManagedCode.Orleans.Identity.Core.Constants;
4-
using ManagedCode.Orleans.Identity.Core.Extensions;
53
using Orleans;
64
using Orleans.Runtime;
75

@@ -15,6 +13,7 @@ public static class OrleansExtensions
1513
/// <param name="filter">The incoming grain call filter instance.</param>
1614
public static string[] GetRoles(this IIncomingGrainCallFilter filter)
1715
{
18-
return RequestContext.Get(ClaimTypes.Role) as string[] ?? [];
16+
var requestContext = RequestContext.Get(OrleansIdentityConstants.USER_CLAIMS);
17+
return requestContext is ClaimsPrincipal user ? user.GetRoles() : [];
1918
}
2019
}

ManagedCode.Orleans.Identity.Core/Serializations/ClaimSurrogate.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Generic;
12
using System.Security.Claims;
23
using Orleans;
34

@@ -8,6 +9,8 @@ namespace ManagedCode.Orleans.Identity.Core.Serializations;
89
[GenerateSerializer]
910
public struct ClaimSurrogate(string type, string value, string valueType, string issuer, string originalIssuer)
1011
{
12+
private const int PropertiesFieldId = 5;
13+
1114
[Id(0)]
1215
public string Issuer { get; set; } = issuer;
1316

@@ -22,6 +25,9 @@ public struct ClaimSurrogate(string type, string value, string valueType, string
2225

2326
[Id(4)]
2427
public string ValueType { get; set; } = valueType;
28+
29+
[Id(PropertiesFieldId)]
30+
public Dictionary<string, string>? Properties { get; set; }
2531
}
2632

27-
// This is a converter which converts between the surrogate and the foreign type.
33+
// This is a converter which converts between the surrogate and the foreign type.
Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Generic;
12
using System.Security.Claims;
23
using Orleans;
34

@@ -8,11 +9,25 @@ public sealed class ClaimSurrogateConverter : IConverter<Claim, ClaimSurrogate>
89
{
910
public Claim ConvertFromSurrogate(in ClaimSurrogate surrogate)
1011
{
11-
return new Claim(surrogate.Type, surrogate.Value, surrogate.ValueType, surrogate.Issuer, surrogate.OriginalIssuer);
12+
var claim = new Claim(surrogate.Type, surrogate.Value, surrogate.ValueType, surrogate.Issuer, surrogate.OriginalIssuer);
13+
if (surrogate.Properties is null)
14+
{
15+
return claim;
16+
}
17+
18+
foreach (var property in surrogate.Properties)
19+
{
20+
claim.Properties[property.Key] = property.Value;
21+
}
22+
23+
return claim;
1224
}
1325

1426
public ClaimSurrogate ConvertToSurrogate(in Claim value)
1527
{
16-
return new ClaimSurrogate(value.Type, value.Value, value.ValueType, value.Issuer, value.OriginalIssuer);
28+
return new ClaimSurrogate(value.Type, value.Value, value.ValueType, value.Issuer, value.OriginalIssuer)
29+
{
30+
Properties = value.Properties.Count == 0 ? null : new Dictionary<string, string>(value.Properties),
31+
};
1732
}
18-
}
33+
}

ManagedCode.Orleans.Identity.Tests/CoreExtensionTests.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Security.Claims;
2+
using ManagedCode.Orleans.Identity.Core.Constants;
23
using ManagedCode.Orleans.Identity.Core.Extensions;
34
using ManagedCode.Orleans.Identity.Core.Serializations;
45
using Orleans.Runtime;
@@ -10,6 +11,8 @@ namespace ManagedCode.Orleans.Identity.Tests;
1011
public class CoreExtensionTests
1112
{
1213
private const string AuthenticationType = "test";
14+
private const string ClaimPropertyKey = "metadata-key";
15+
private const string ClaimPropertyValue = "metadata-value";
1316
private const string ClaimValue = "claim-value";
1417
private const string CustomClaimType = "custom";
1518
private const string Delimiter = "|";
@@ -55,10 +58,10 @@ public void OrleansExtensions_ReadRolesFromRequestContext()
5558
{
5659
try
5760
{
58-
var roles = new[] { RoleUser, RoleAdmin };
59-
RequestContext.Set(ClaimTypes.Role, roles);
61+
var user = CreatePrincipal();
62+
RequestContext.Set(OrleansIdentityConstants.USER_CLAIMS, user);
6063

61-
OrleansExtensions.GetRoles(null!).ShouldBe(roles);
64+
OrleansExtensions.GetRoles(null!).ShouldBe([RoleUser, RoleAdmin], ignoreOrder: true);
6265
}
6366
finally
6467
{
@@ -87,6 +90,18 @@ public void ClaimConverters_RoundTripClaimsPrincipal()
8790
convertedPrincipal.Identity!.AuthenticationType.ShouldBe(AuthenticationType);
8891
}
8992

93+
[Fact]
94+
public void ClaimConverter_RoundTripsClaimProperties()
95+
{
96+
var converter = new ClaimSurrogateConverter();
97+
var claim = new Claim(CustomClaimType, ClaimValue);
98+
claim.Properties[ClaimPropertyKey] = ClaimPropertyValue;
99+
100+
var convertedClaim = converter.ConvertFromSurrogate(converter.ConvertToSurrogate(claim));
101+
102+
convertedClaim.Properties[ClaimPropertyKey].ShouldBe(ClaimPropertyValue);
103+
}
104+
90105
[Fact]
91106
public void ClaimsPrincipalConverter_ReturnsEmptyPrincipalForEmptySurrogate()
92107
{

0 commit comments

Comments
 (0)