Linda Lawton - DaImTo
Linda Lawton - DaImTo

Reputation: 116938

Identity server API Policy and roles

We currently have an identity server built using Identityserver4 2.0. We are in the process of adding some policy guidelines to our API. I have been reading a number of tutorials mainly this one Policy-Based Authorization in ASP.NET Core

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("RequireElevatedRights", policy => policy.RequireRole("SuperAdministrator", "ChannelAdministrator"));
    });
}

[Authorize(Policy = "RequireElevatedRights")]
public class ChannelAdministrationController: Controller
{
}

I think we have some miss conceptions on how this should be done. As i understand it our API will check the current users authorization and build the policy around that. Basically we are checking the token that the user sends in the header correct?

My issue with this is if the user has had their permissions changed after the token was created. Given that access tokens are valid for 1 hour and refresh token's don't expire. Wont this mean that a user with a valid token will still be able to access things for an hour?

How can we ensure that the current authenticated user still actually has permissions to do what is in the claims?

Upvotes: 3

Views: 2719

Answers (2)

Aeseir
Aeseir

Reputation: 8414

While my answer may not be as profound as the commentary and the previous one by Tseng, i had experimented this a bit and i took a slightly different approach.

I was required to dump roles into token that was issued, and yes you are 100% correct that unless the token is updated (my case was 1 hour) they could have access for that 1 hour or longer if api server wasn't hit by any calls.

My workaround was in two points:

  • forcefull hit on API server to verify user (every 60 seconds)
  • Implemented token wipe for the user once their roles got changed on identityserver4

It may not be pretties solution but what it meant that the minute the super admin changed your role(s), it wiped the users token from the db store if there was one. The frontend would hit the api server after 60 seconds (or before if they make a call), forcing the user to be redirected to the login page again to obtain the new token.

This meant that at worst case scenario user could have access for 60 seconds after their token was wiped.

Not the cleanest solution but did the trick for the experiment.

Upvotes: 0

Tseng
Tseng

Reputation: 64150

That's the main point of the (jwt) tokens, that you don't have to hit a database on every request.

The identity token (long lived token) and the access token (short lived, <= 60 mins) shouldn't contain authorization related data.

Identity token should only contain claims that rarely change and are connected to the identity of the user (username, first + last name, birthday, email, email_verified, etc.).

Don't put roles like "administrator" if you expect it to change frequently.

Authorization (is user A permitted to create this and that, or read/view a resource) should be done in a separate (per service) database and you fetch it from there (and cache if necessary).

Your alternative, if you really have put such "permissions" inside the token or have case where it needs to be effective immediately (compromised account, or fire a worker), then you can revoke the token.

But keep in mind, revocation endpoint only applies to refresh and reference (also called opaque) tokens.

You can't revoke JWT tokes out of the box. Of course you can put an unique (and random) id inside the token when its generated put it in a memory cache (redis, local cache) with the expiration time of the token.

On each request you check if that id is still in the cache. If its there and token is valid, allow access. Otherwise deny it.

And when you do some sensitive changes, have a message sent to your message bus (rabbitmq, azure queues, redis), trigger an handler which removes that id from the cache and on next request the value isn't found in the cache and will deny the access

Upvotes: 4

Related Questions