1
votes

So I am writing a Blazor webassembly application, with asp.ner core Identity. I need to get the ID of the current user, not the username that the methods in Identy give.

The method

Context. User.identity.name

gives the username but I need the ID for a fk in a model/table.

I can't use the username as usernames might change.

I have searched the net, however I keep seeing just the username returned.

Any assistance will be greatly appreciated.

3

3 Answers

7
votes

I use this with the boiler plate Identity Server:

@page "/claims"
@inject AuthenticationStateProvider AuthenticationStateProvider

<h3>ClaimsPrincipal Data</h3>

<p>@_authMessage</p>

@if (_claims.Count() > 0)
{
    <table class="table">
        @foreach (var claim in _claims)
        {
            <tr>
                <td>@claim.Type</td>
                <td>@claim.Value</td>
            </tr>
        }
    </table>
}

<p>@_userId</p>

@code {
    private string _authMessage;       
    private string _userId;
    private IEnumerable<Claim> _claims = Enumerable.Empty<Claim>();

    protected override async Task OnParametersSetAsync()
    {
        await GetClaimsPrincipalData();
        await base.OnParametersSetAsync();
    }

    private async Task GetClaimsPrincipalData()
    {
        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity.IsAuthenticated)
        {
            _authMessage = $"{user.Identity.Name} is authenticated.";
            _claims = user.Claims;
            _userId = $"User Id: {user.FindFirst(c => c.Type == "sub")?.Value}";
        }
        else
        {
            _authMessage = "The user is NOT authenticated.";
        }
    }
}
5
votes

In Startup.cs, add the following line in ConfigureServices

services.AddHttpContextAccessor();

In your Blazor component, add the following lines on the top of the file

@using System.Security.Claims
@inject IHttpContextAccessor HttpContextAccessor

In your method, add the following lines to get the UserId

var principal = HttpContextAccessor.HttpContext.User;
var loggedInUserId = principal.FindFirstValue(ClaimTypes.NameIdentifier);
1
votes

Not an answer, just a tip on using breakpoints to find the answer. My site is Blazor Server, so it's very possible that things are different-- in my case, Brian Parker's solution didn't work for me, so I did the following:

var user = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User;
if (true) {} // or any other code here, breakpoint this line

If you set a breakpoint right after retrieving the user, run the app and hover the user variable in the code when it breaks, it will pop up the complete object. By hovering various fields, you can investigate. I found that the claim type strings were big long things like "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"

So the answer that worked for me was:

var user = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User;
string userId = user.FindFirst(c => c.Type.Contains("nameidentifier"))?.Value;

My point is that when the docs are complicated, or when the technology is changing fast so that one day's right answer is the next day's wrong lead, you can achieve a lot just by using VS to dig around.

Hope that helps someone. :D