Maksim
Maksim

Reputation: 45

How to get OpenID info in ASP.NET core WEB API controllers

There are two applications:

  1. OneLogin identity provider with enabled OpenID connect.
  2. My ASP.NET core WEB API which is resource server for frontend application.

Initially I had only authorization logic implemented, using the following code:

serviceCollection
            .AddAuthentication(options =>
            {
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.Audience = clientId;
                options.Authority = authority;
            });

I set [AuthorizeAttribute] for my controller and the authorization logic worked fine. Now I need to get information about user in my controller. For this I would like to use OpenID info. I modified my code by adding OpenID connect:

serviceCollection
            .AddAuthentication(options =>
            {
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.Audience = clientId;
                options.Authority = authority;
            })
            .AddOpenIdConnect(options =>
            {
                options.ClientId = clientId;
                options.Authority = authority;
                options.GetClaimsFromUserInfoEndpoint = true;
            });

But I still see only access_token claims in my controller (User.Identity). What have I missed?

Upvotes: 1

Views: 4024

Answers (2)

Tore Nestenius
Tore Nestenius

Reputation: 19921

You have two options.

you could add the desired claims to the access token (In the ApiScope or ApiResources) and then access then through the AddJwtBearer in the API.

Alternatively, you can take the access-token and sent it to the token introspection endpoint, from the response you can get more details about the user. You can also manually call the userinfo endpoint using the access token. However, AddJWtBearer won't call these endpoints for you. The helper classes in IdentityModel can help you to do that.

Adding AddOpenIdConnect to the API, just to get the user details is the wrong approach.

To complement this answer, I wrote a blog post that goes into more detail about this topic: Debugging OpenID Connect claim problems in ASP.NET Core

Upvotes: 1

Max
Max

Reputation: 1715

You can extend HttpContext like this (don´t need to do it this way, but its a bit nicer to call in your controller you could put the code straight into your controller).

public static class AuthExtensions
{
    public static string GetUserId(this HttpContext httpContext)
    {
        if (httpContext.User == null)
            return string.Empty;

        return httpContext.User.Claims.Single(x => x.Type == "id").Value;
    }

    public static UserRole GetUserRole(this HttpContext httpContext)
    {
        if (httpContext.User == null)
            throw new InvalidOperationException("User not set on httpContext.");

        var roleStr = httpContext.User.Claims.Single(x => x.Type == ClaimTypes.Role).Value;
        return (UserRole) Enum.Parse(typeof(UserRole), roleStr);
    }
}

Then You can call those from your controller var userId = Request.HttpContext.GetUserId();. Note that what´s in the Claims depends on what you did put into into it when creating the token. You might not have a role for instance. If you don´t know, you can lookup what your tokens contain by copy/pasting one into jwt.io.

Upvotes: 0

Related Questions