Skip to content
This repository has been archived by the owner on Sep 18, 2021. It is now read-only.

Having idsvr deny Access when user doesn't have the required claim or scope #750

Closed
parkinsona opened this issue Jan 13, 2015 · 12 comments
Closed

Comments

@parkinsona
Copy link

Hi,

Sorry if this has been covered before, but I couldn't find anything specific to my scenario.

I have 2 RPs that each manage their roles separately.
For RP1 we store the role claims as RP1.Role. (Eg RP1.Role: Admin)
For RP2 we store the role claims as RP2.Role. (Eg. RP2.Role: User)

In idsvr we have 2 implicit clients setup for each RP.
One client has a scope of RP1, which includes the RP1.Role claim.
the other client has scope RP2, with RP2.Role claim.

This has been done because a user may be admin in RP1, but not necessarily in RP2.

I'm unsure what will happen if a user only has role claims for RP1 and not RP2.
From my understanding, they should be able to log in to both RPs regardless of the scopes being returned. The RPs are then responsible to restrict their pages based on the claims returned.

However, is there a way in identity server to not log a user in to a RP if they are missing a required scope?

My concern is that someone consuming my idsvr implentation may not setup their RP roles checking correctly. In this scenario if they skip the checks, and their user doesn't have the corresponding RP role claim, they'd be allowed in when they shouldn't be.

I hope that all makes sense. I did see there wasa required attribute on scope, but the description seems to suggest it won't do what I need.
" Specifies whether the user can de-select the scope on the consent screen"

Any help would be great.

@leastprivilege
Copy link
Member

There is an extensibility point called ICustomTokenRequestValidator - this let's you add custom code like role checks to the token pipeline. give that a try.

@parkinsona
Copy link
Author

Hi Dom,

I assume you mean ICustomRequestValidator? I'm guessing it got renamed somewhere along the way.

I've had a look at the 2 methods for ValidateAuthorizeRequestAsync & ValidateTokenRequestAsync.
I'm probably wrong, but as these are both requests, they won't have the claims for the user yet. So how could I check the user has a particular claim?

I did see there was a ValidatedScopes property for each of the Request classes. Is this what I'm after?

Looks like Brock has already answered a question similar to this a few days ago on stackexchange:
http://stackoverflow.com/questions/27823150/access-requested-client-from-iuserservice/27825216#27825216

He's also added a todo item for a sample on this... .
IdentityServer/IdentityServer3.Samples#53

@leastprivilege
Copy link
Member

you are right - right now the custom validator runs before claims are being produced.

The assumption was that you can do a DB request of some sort (you have sub, client id and scopes) to determine if the user is allowed or not. Not sure we can change that behavior for RTM - or if we have to postpone it.

@parkinsona
Copy link
Author

hmmmm so I'd essentially be looking up the user in the db initially to get their claims for validation, and then idsvr would repeat the lookup when it does its thing.

I would prefer to wait for this to be implemented as part of identity server. We already have a work around in place, which is fine at the moment. Long term though, this feature would be great as we begin to get RPs outside our control.

@leastprivilege
Copy link
Member

But doing it the other way round would mean that we first fetch the claims (as opposed to maybe a simple db check if user x is allowed for client y) and then potentially deny access. Either way it is not perfect.

@leastprivilege
Copy link
Member

I personally don't think that the absence/presence of claims for a client are the best way to determine if a user has access or not. I would rather prefer an authorization rule of some sort.

@parkinsona
Copy link
Author

When you talk about the authorization rule, do you mean the ResourceAuthorize? Where you can write your own custom implementation?

@leastprivilege
Copy link
Member

no - in identity server - something to think about for future releases.

@brockallen
Copy link
Member

Closing because #776

@parkinsona
Copy link
Author

I missed the notifications for this item. I'll keep an eye on 776.

@parkinsona
Copy link
Author

It looks like this update is still a while off.
In the meantime, I need to reject users that don't have certain claims for a RP.

I tried the following in the OpenIdConnectAuthenticationNotifications.

SecurityTokenValidated = async n =>
                    {
                        var id = n.AuthenticationTicket.Identity;

                        //Change the Name Claim Type
                        id = new ClaimsIdentity(id, null, id.AuthenticationType, ClaimConstants.Name, ClaimConstants.Role);

   if (id.FindFirst(ClaimConstants.Role) == null)
                        {

                           throw new HttpException(403, "You do not have any roles configured for the application");
                        }

                   }

This is working, and it will reject the user, however the error being returned by MVC is:

This type of page is not served.

I don't think this is the best place for me to set this up or not.
Perhaps I need to check this in the global Authorize filter instead?

@leastprivilege
Copy link
Member

Yes - global authZ filter would be better.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants