0

We've started implementing a new Web API with ASP.NET Core 2.2 and it has been decided that it should use Identity Server 4 for authentication/authorization duties. Furthermore, its Skoruba implementation has been chosen as it looks like it should fulfill most, if not all our needs in that regard.

We got the identity server and Skoruba up and running, but when it comes to consuming the JWT token in our own API, even assigning just one role to the test user, we'll keep hitting the same brick wall. The following request to the Skoruba API will respond with a 200:

http://localhost:5000/connect/token:

http://localhost:5000/connect/token

It successfully returns a JSON string with access_token, expires_in and token_type ("Bearer").

After that, a request to the http://localhost:5000/connect/userinfo route of the API with the following header

enter image description here

will also respond with a 200 and return the following JSON string:

{
    "sub": "aeccf460-7d0d-41ae-8b52-a051138f5c05",
    "role": "Administrator",
    "preferred_username": "dev",
    "name": "dev"
}

Please take notice that "role": "Administrator" assigned to user dev is something I set up myself using the Skoruba Admin UI, so that JSON is pretty much what I wanted. So for all intended purposes it looks like I have the information I need right now. I just can't consume it. If I try to retrieve the JWT token in our own back end, I am successful (this is obviously just for testing purposes):

[HttpGet("GetAccessToken")]
[AllowAnonymous]
public string GetAccessToken()
{
   var accessToken = HttpContext.Request.Headers["Authorization"];
   var token = accessToken.First().Remove(0, "Bearer ".Length);
   return token;
}

With all that said, onto the actual problem: calls to a route that demands authorization in our API are treated in the same fashion as calls to Skoruba's userinfo action (particularly, the headers):

enter image description here

Inside this same Controller ("Foo"), I implemented a simple Get method, which should only be accessed with the correct role, which I assume is information fetched from HttpContext.Request.Headers["Authorization"] and hoped the framework would use it accordingly:

[HttpGet]
[Authorize(Roles = "Administrator")] 
public IActionResult Get()
{
   try
   {
       var response =  ConvertListToJsonResponse(GetAll()); //Don't mind me
       return Ok(response);
   }
   //...
}

At this point, my API server responds with the infamous 403 Forbidden status code. Not sure where to go from here and research proved unwieldy so far. Any help is appreciated, I'll provide more code and info if necessary.

EDIT

This is the generated token:

eyJhbGciOiJSUzI1NiIsImtpZCI6IjA4NTMzNmFmZTY0Yzg2ZWQ3NDU5YzE5YzQ4ZjQzNzI3IiwidHlwIjoiSldUIn0.eyJuYmYiOjE1Njg3NDU5NTgsImV4cCI6MTU2ODc0OTU1OCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwL3Jlc291cmNlcyIsImNsaWVudF9pZCI6ImF1dGhfdGVzdCIsImNsaWVudF9hY2Nlc3NfcmlnaHRzIjpbImxpc3QiLCJhcHByb3ZlIiwia2VlcCJdLCJzdWIiOiJhZWNjZjQ2MC03ZDBkLTQxYWUtOGI1Mi1hMDUxMTM4ZjVjMDUiLCJhdXRoX3RpbWUiOjE1Njg3NDU5NTgsImlkcCI6ImxvY2FsIiwic2NvcGUiOlsib3BlbmlkIiwicHJvZmlsZSIsInJvbGVzIl0sImFtciI6WyJwd2QiXX0.Ihsi6W5ukGcZ4Chkuk5XMaoqTkUR_1hBQlIcdHtMWiBA-EyAIncX5STCng_6ZPgN89Np6Y_hemFFyVtHEdN_vP6i0HuaXgznzrnJ4zq4Iiz9jxpZqpSSE9cXpSG8hPOZe5kGfD2J6_GPxnraGH_1ZF94AhmlspIvqFAAQrQ-0c7-dCduP4ledkQvBKz-rXszGp35W7Gb5nvpcVt4oe67mqETdwtgGengk2eCwHeKdA94EYnj_HErPNTjJhh5k75fDQ0IiOS-xHRK8BQmLhRh_UZwB3H5qZymFJNr_yb-ljFqIeEHptSWLBO1XrKYs1BqB9KwxIROKqmxeNGTnpCUSQ

The resulting payload:

{
  "nbf": 1568745958,
  "exp": 1568749558,
  "iss": "http://localhost:5000",
  "aud": "http://localhost:5000/resources",
  "client_id": "auth_test",
  "client_access_rights": [
    "list",
    "approve",
    "keep"
  ],
  "sub": "aeccf460-7d0d-41ae-8b52-a051138f5c05",
  "auth_time": 1568745958,
  "idp": "local",
  "scope": [
    "openid",
    "profile",
    "roles"
  ],
  "amr": [
    "pwd"
  ]
}

I see the claims I added to the client, but what I really need at the moment is simple Authentication, which I suppose should be provided by a role. Or am I completely off?

makoshichi
  • 2,310
  • 6
  • 25
  • 52
  • 1
    Do you add the claims to the `id_token` or the `access_token` and which token is sent to the api? Please read my answer [here](https://stackoverflow.com/questions/53976553/identityserver4-role-based-authorization-for-web-api-with-asp-net-core-identity/54004765#54004765) for more information. –  Sep 16 '19 at 20:01
  • Can you share the content of your JWT access token please? – mackie Sep 17 '19 at 08:02
  • @mackie Added the access token and the payload, if you care to take a look, I appreciate it – makoshichi Sep 17 '19 at 19:25
  • @RuardvanElburg Many thanks, your comment and answer in the other post (in fact, the whole post itself) pointed me towards the right direction – makoshichi Sep 20 '19 at 14:50

1 Answers1

0

This question, and more specifically, this answer helped me to understand what was going on and map Skoruba's UI functionalities to IdentityServer4 inner workings. Credits goes to Ruard van Elburg.

makoshichi
  • 2,310
  • 6
  • 25
  • 52