keycloak-authorization-services-dotnet
keycloak-authorization-services-dotnet copied to clipboard
Get username and roles from keycloaks JWT token?
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?
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; }
}