Well, I just did it. I have to add .AddAccountClaimsPrincipalFactory< ArrayClaimsPrincipalFactory<RemoteUserAccount>>();
to OidcAuthentication
. So the final code in Program.cs
in Client
side is:
builder.Services.AddOidcAuthentication(options =>
{
builder.Configuration.Bind("Auth0", options.ProviderOptions);
options.ProviderOptions.ResponseType = "code";
}).AddAccountClaimsPrincipalFactory<
ArrayClaimsPrincipalFactory<RemoteUserAccount>>();
Also I added this code:
public class ArrayClaimsPrincipalFactory<TAccount> : AccountClaimsPrincipalFactory<TAccount> where TAccount : RemoteUserAccount
{
public ArrayClaimsPrincipalFactory(IAccessTokenProviderAccessor accessor)
: base(accessor)
{ }
// when a user belongs to multiple roles, IS4 returns a single claim with a serialised array of values
// this class improves the original factory by deserializing the claims in the correct way
public async override ValueTask<ClaimsPrincipal> CreateUserAsync(TAccount account, RemoteAuthenticationUserOptions options)
{
var user = await base.CreateUserAsync(account, options);
var claimsIdentity = (ClaimsIdentity)user.Identity;
if (account != null)
{
foreach (var kvp in account.AdditionalProperties)
{
var name = kvp.Key;
var value = kvp.Value;
if (value != null &&
(value is JsonElement element && element.ValueKind == JsonValueKind.Array))
{
claimsIdentity.RemoveClaim(claimsIdentity.FindFirst(kvp.Key));
var claims = element.EnumerateArray()
.Select(x => new Claim(kvp.Key, x.ToString()));
claimsIdentity.AddClaims(claims);
}
}
}
return user;
}
}