Reputation: 55
Application is Blazor Server .NET Core 5.0
I am using .NET Core's Identity system and I am running into a problem. I want to have the person's first name stored with the Identity so I can call on it easily.
Currently I have a class overriding the base identity:
public class ApplicationUser : IdentityUser
{
public ApplicationUser() : base() { }
[StringLength(100)]
public string FirstName { get; set; }
[StringLength(100)]
public string LastName { get; set; }
}
My startup.cs has:
services.AddDefaultIdentity<ApplicationUser>(options => {
options.SignIn.RequireConfirmedAccount = true;
}
)
In my mind that should force the program's intellisense to understand ApplicationUser is the default class when looking for identity.
However, when I try to call:
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
It only returns "IdentityUser" data rather than my custom ApplicationUser class.
Is there something I am missing with what AuthenticationStateProvider is returning or a type casting I am missing?
Also, if this is completely incorrect, should I do this with Claims? If so, I cannot find a concrete way to effectively use claims with Blazor Server.
Upvotes: 3
Views: 6142
Reputation: 45674
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Execute in the Package Manager Console:
Insert values to the FirstName and LastName created in the Users table
Create a class named: ApplicationUserClaimsTransformation
using Microsoft.AspNetCore.Authentication;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WebApplication3.Data;
using WebApplication3.Models;
using System.Security.Claims;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Components.Authorization;
public class ApplicationUserClaimsTransformation : IClaimsTransformation
{
private readonly UserManager<ApplicationUser> _userManager;
public ApplicationUserClaimsTransformation(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var identity = principal.Identities.FirstOrDefault(c => c.IsAuthenticated);
if (identity == null) return principal;
var user = await _userManager.GetUserAsync(principal);
if (user == null) return principal;
// Add or replace identity.Claims.
if (!principal.HasClaim(c => c.Type == ClaimTypes.GivenName))
{
identity.AddClaim(new Claim(ClaimTypes.GivenName, user.FirstName));
}
if (!principal.HasClaim(c => c.Type == ClaimTypes.Surname))
{
identity.AddClaim(new Claim(ClaimTypes.Surname, user.LastName));
}
return new ClaimsPrincipal(identity);
}
}
services.AddScoped<IClaimsTransformation,
ApplicationUserClaimsTransformation>();
@page "/"
@inject AuthenticationStateProvider AuthState
@using System.Security
@using System.Security.Claims
@foreach(var c in user.Claims)
{
<div>@c.Type: @c.Value</div>
}
@code
{
private ClaimsPrincipal user;
protected override async Task OnInitializedAsync()
{
var x = await AuthState.GetAuthenticationStateAsync();
user = x.User;
await base.OnInitializedAsync();
}
}
Note: You should alter the IdentityUser name to ApplicationUser in the Startup class, LogOut.cshtml file, _LoginPartial.cshtml file and in the definition of the ApplicationDbContext class:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
Upvotes: 6