I have a Blazor client (WASM) app that integrates with AAD B2C for authentication.
After authentication, I want to call my own API for further authorisation information. The reason I want to do this rather than getting B2C to call my API is I will have series of different apps using the same B2C, with different claims, roles and other information etc.
I've tried every tutorial I can find, but nothing seems to wire up.
My Program.cs has this:
builder.Services.AddMsalAuthentication(options =>
{
var settings = config.AzureAdB2C;
var authentication = options.ProviderOptions.Authentication;
authentication.Authority = $"{settings.Instance}{settings.Domain}/{settings.SignInPolicy}";
authentication.ClientId = settings.ClientApplicationId;
authentication.ValidateAuthority = false;
options.ProviderOptions.DefaultAccessTokenScopes.Add($"{settings.ServerAppId}/{settings.DefaultScope}");
//options.ProviderOptions.Cache.CacheLocation = "localStorage";
});
builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
And for example, I've tried this:
builder.Services.AddScoped<IClaimsTransformation, UserInfoClaims>();
public class UserInfoClaims : IClaimsTransformation
{
private static IEnumerable<SimpleClaim> roles;
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
...
But it doesn't get hit.
Is it possible to rewrite claims in WASM after B2C authentication?
And if not, is there an event I can wire up to after successful authentication to just manage my own role-like alternative?
This can be done by implementing your own AccountClaimsPrincipalFactory
public class ExampleClaimsPrincipalFactory<TAccount> : AccountClaimsPrincipalFactory<TAccount>
where TAccount : RemoteUserAccount
{
public ExampleClaimsPrincipalFactory(IAccessTokenProviderAccessor accessor)
: base(accessor)
{
//Any dependency injection or construction of objects
//inside this constructor usually leads to wasm memory exceptions
}
public async override ValueTask<ClaimsPrincipal> CreateUserAsync(TAccount account, RemoteAuthenticationUserOptions options)
{
var user = await base.CreateUserAsync(account, options);
if (account != null)
{
//Add logic here to get custom user information
//Add Claims to the user identity like so
var identity = user.Identity as ClaimsIdentity;
identity.AddClaim(new Claim("type", "value"));
}
return user;
}
}
Then on start up when adding authentication you do the following
builder.Services.AddMsalAuthentication()
.AddAccountClaimsPrincipalFactory<ExampleClaimsPrincipalFactory<RemoteUserAccount>>();