keycloak-authorization-services-dotnet icon indicating copy to clipboard operation
keycloak-authorization-services-dotnet copied to clipboard

Get username and roles from keycloaks JWT token?

Open basprins opened this issue 1 year ago • 1 comments

Hi, I hope you are willing to spend a little time on explaining how this works. I've been trying to secure my backend api (Asp.net core) and after a long time searching got it working with your library.

I think I'm struggling most with how things works conceptually between ASP NET core and how deep things really integrate with keycloak authorization library. Bear with me...

So I have setup your library pretty straight forward, copied most of it from the docs:

For development/production I have different app settings, this is what I have for development anyway.

  "Keycloak": {
    "realm": "projects",
    "auth-server-url": "http://keycloak/keycloak",
    "ssl-required": "none",
    "resource": "projects",
    "verify-token-audience": false,
    "credentials": {
      "secret": ""
    },
    "confidential-port": 0
  },

Adding the auth service:

builder.Services.AddKeycloakAuthentication(builder.Configuration);

And using the following middlewares

var app = builder.Build();
app.UseHttpsRedirection();
app.UseCors(PolicyName);
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

As I already said, the basics work perfectly. I can authenticate in the angular app (via a google provider), have angular keycloak copy the bearer JWT token to the http headers invoked on the backend, and observe that the JWT token gets validated against keycloak. Super cool! Proud moment, although I didn't do much ;-).

But now, I need the username of the token in the backend (the email address really, but in my case username == email address). I can grab it from the keycloak profile in angular. I could of course do that, and just add the username to the http header as well. But something tells me that would be backwards, I have the feeling retrieving the username from the JWT token is part of the deal with this library. Or... part of the integration with ASP NET identity (System.Security.Principal).

But that's where things become blurry for me. Is your keycloak integrating with the ASP NET identity framework? I tried to simply get the Name from Request.HttpContext.User.Identity.Name in my HttpController, but that remains null so I guess I am in the wrong place then?

I also cloned your repository and searched for stuff involving getting the username from the JWT token, but ended up nowhere.

I hope I make any sense, I am still rather new on ASP.NET.

Can you give me some hints?

basprins avatar Sep 08 '23 20:09 basprins

You can get it just like in any other authentication method, here's a sample that I use:

using System.Security.Claims;
using Keycloak.AuthServices.Common;

namespace Your.API;

public class CurrentUser : ICurrentUser
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public CurrentUser(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public Guid? Id
    {
        get
        {
            var id = _httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier);

            if (!Guid.TryParse(id, out var guid))
                return null;

            return guid;
        }
    }

    public string? Email => _httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.Email);
}

public interface ICurrentUser
{
    Guid? Id { get; }

    string? Email { get; }
}

victor-borges avatar Sep 10 '23 21:09 victor-borges