Skip to content
This repository has been archived by the owner on Dec 13, 2022. It is now read-only.

Token / PermissionGrants #347

Closed
ThatDeveloper opened this issue Sep 26, 2016 · 25 comments
Closed

Token / PermissionGrants #347

ThatDeveloper opened this issue Sep 26, 2016 · 25 comments
Labels

Comments

@ThatDeveloper
Copy link

Hey IdentityServer Team,

I have following problem:
I want to invalidate a user. I googled and I found in IdentityServer3 UseIdentityServerBearerTokenAuthentication. I found the same for IdentityServer4 but I don't understand how to use. Every sample talks about an API usage. (I use Cookie)

What I want:

IS1 => IdentityServer
MVC1 => e.x. CoolMvcSite
MVC2 => e.x. ShitMvcSite

User => MVC1
User clicks Login => Redirect to IS1
Login on IS1 => logged in in MVC1
^^^^^^^^^^^^^^^^^^^^^^^ this workes. But now I want to invalidate a Usersession. (Block him, or he logged in on another device)
Invalidate User Session for user on all Clients (MVC1, MVC2)

User goes to some protected stuff => Redirect to IS1, has to login again

Is it possible to say that an MvcApplication caches IS1 response for user 5 minutes, after 5 minutes on next user request MVC application checks on IS1 if valid.
Or that the IS1 sends on Invalidation a request to a controller on every client application to tell them news.

@ThatDeveloper
Copy link
Author

Addition: I already read the articles provided in gitter.im chat and on blogs. None of them could help me to solve that problem. :/

@ThatDeveloper
Copy link
Author

ThatDeveloper commented Sep 27, 2016

Configuration Startup of MVC1 and IS1: http://hastebin.com/qofipuduyi

@kdaveid
Copy link
Contributor

kdaveid commented Sep 27, 2016

Why not use reference token to have full controll?
Check with this: #313

@ThatDeveloper
Copy link
Author

Because I can't find the entries in the database to remove them. :/

@Simply-Awesome
Copy link

Once the user has a token, they can always access the resource according to the claims described within it!

You can:

  • Shorten the lifespan of the access_token (current default is 1 hour)
  • Use Refresh Tokens that you disable at will.

If its an emergency, (i.e. you cannot wait for the access_token (or refresh token) to expire), you can:

  • take the resource down temporarily
  • update the resource to have an additional claim (and/or scope) that the user will not already have.

@ThatDeveloper
Copy link
Author

But why is there no entry in PermissionGrantStore? I made it like in the EF sample.

@brockallen
Copy link
Member

But why is there no entry in PermissionGrantStore? I made it like in the EF sample.

Depending on the flow and configuration, there might not need to be a record in the DB in IdentityServer.

@ThatDeveloper
Copy link
Author

Implicit flow, Reference, Store Async is not getting called.

This does not work (no record in database):
await _persistedGrantService.RemoveAllAsync(sid, null);

But I want to e.x. block a user (change user entry (no problem) and remove his sessions)

@brockallen
Copy link
Member

brockallen commented Oct 2, 2016

RemoveAllGrantsAsync requires both params to be passed, so null as the client might explain why it's not working.

Do you need a RemoveAllGrants where just the subject is passed, and the semantics are that all prior consents and tokens are revoked for all clients?

@ThatDeveloper
Copy link
Author

ThatDeveloper commented Oct 2, 2016

I modified it. It allows null. But the problem is somewhere else. I don't even get a record. Here the Login method.

Account / Login

       [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Login([Bind("Username, Password, ReturnUrl")] LoginViewModel model)
        {
            if (!ModelState.IsValid) return View(model);
            if (_userService.ValidateCredentials(model.Username, model.Password))
            {
                var user = _userService.FindByUsername(model.Username);
                if (!user.Enabled) return View("../Error/Blocked");
                if (!user.EMailVerified) return View("../Error/NotActivated");

                await HttpContext.Authentication.SignInAsync(user.Subject, user.Username);
                return Redirect(_interaction.IsValidReturnUrl(model.ReturnUrl) ? model.ReturnUrl : "~/");
            }
            ModelState.AddModelError("", "Invalid username or password.");

            return View(model);
        }

I inject this:
private readonly IIdentityServerInteractionService _interaction; private readonly IPersistedGrantStore _persistedGrantStore;

GrantStore is the same as in EF example (only 1 line modified on logout).
interaction is Default too.

@brockallen
Copy link
Member

brockallen commented Oct 2, 2016

I'm sorry -- I am not following how the persisted grant store relates to login sessions (because they aren't the same thing). If you have a requirement where a user can only be logged into one app at a time, then that's up to you to implement on your own in the app with some check back to a central DB that knows the user's last login session at which app.

@ThatDeveloper
Copy link
Author

It's about the reference token.
Somewhere he has to be stored in my opinion. I mean, I want to log him out (without he doing it, I want the programmatic way) but how?

@ThatDeveloper
Copy link
Author

I can't find the store / service for reference tokens. Any idea?

@ThatDeveloper
Copy link
Author

This store does not get called. I wrote above.
But the login / logout works. I'm soo confused.

@ThatDeveloper
Copy link
Author

(But the programmatic logout doesn't => RemoveAllAsync does not work because StoreAsync does not get called.)

@brockallen
Copy link
Member

So am I. I'm sorry. I have a feeling that your expectation is how it's supposed to work is not lined up with how it actually works.

When a user logs in they're assigned a session ID in their cookie. This is added to id_tokens when the user logs into client apps. Also, if the client app requests API access then they're issued a access token. If the access token default configuration is changed to a reference token then that's when the persistent grant store would be used -- but it's not the default.

@ThatDeveloper
Copy link
Author

It seems like I'm too stupid. ^^

What I would like to achive is the following.

User can log in into IdSrv. User can log out.
When a user is logged in I would like, that he can use the mvc app. (implicit / reference)

Now, if I block him or if he e.x. changes password I want to "Cancel" his session so he is logged out of IdSrv => IdSrv notifies all MVC apps that user not valid => new login redirect to IdSrv.

I want to have the full control about the user.
e.x. MVC checks all 5 minutes for changes in claims at IdSrv for user.
if user signs out or gets blocked all mvc apps get notified for a change in user => user cant use apps because reference token not valid => new Login redirect.

@brockallen
Copy link
Member

brockallen commented Oct 3, 2016

Now, if I block him or if he e.x. changes password I want to "Cancel" his session so he is logged out of IdSrv => IdSrv notifies all MVC apps that user not valid => new login redirect to IdSrv.

The only thing like this in IdSvr is the IsActive API on the IProfileService -- this API allows you to say that a user is no longer allowed to get new tokens (id_token or access_token) or existing refresh tokens or reference tokens will no longer validate. But this only really works for the "disable user" scenario.

If you want to disable a user's existing session in an existing app and just make them login again, you'll have to build this yourself with your own custom check in the MVC app for this.

@ThatDeveloper
Copy link
Author

Like how?

Can't I just use something like a Cache Timespan on Mvc App for revalidating reference token?

@ThatDeveloper
Copy link
Author

I thought about an Endpoint on the apps like logout, for changes on user claims for e,x. or user state.

@brockallen
Copy link
Member

I think you need to spend some more time learning how OIDC and OAuth2 work. This seems to be your major mental hurdle, because you're conflating things that aren't related. Once you have a better understanding of them then I think you'll have an easier time with your requirement.

@ThatDeveloper
Copy link
Author

IsActive gets called on Login, how can I say how often this get's called e.x.?

@leastprivilege
Copy link
Member

that would be a new issue - but here's the low down: #258

closing this one now...OK?

@lock
Copy link

lock bot commented Jan 15, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

5 participants