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

Multi Tenancy Cookies #947

Closed
c0dem0nkee opened this issue Feb 18, 2015 · 21 comments
Closed

Multi Tenancy Cookies #947

c0dem0nkee opened this issue Feb 18, 2015 · 21 comments
Labels

Comments

@c0dem0nkee
Copy link

Hi guys,

My situation is this:

I have a multi-tenanted site using idsrv. The site uses a sub-domain to indicate the tenant in question e.g. beta.mytest.com, delta.mytest.com, etc. When calls to idsrv are made, I pass the tenant name in the acr option which is then processed by my custom user service. This all works as expected but for one issue.

I sign in to one tenant and get a token back, if I open another tab and attempt to sign in for another tenant, idsrv simply returns the principal held in the cookie for the first tenant. Is there a way I can customise the CookieAuthenticationOptions so I can store cookies on a tenant basis?

@brockallen
Copy link
Member

Why would it -- aren't the different tenants on different host names?

@c0dem0nkee
Copy link
Author

Yes, you are correct, however, my idsrv is set on a separate site using its own host e.g. idsrv.mytest.com. When I local login on idsrv, a cookie is held for that host. When I attempt to login for a tenant, I'm redirected to the idsrv, which seems to pick up its cookie and then give me the principal from the previous successful login. Sorry if this sounds confusing, I may be barking up the wrong tree here

@loctanvo
Copy link
Contributor

Well, that's the whole concept of SSO. The user logs in once, and he/she is logged in to all other applications. Not sure what you're trying to achieve, but there are some mechanisms for triggering a new log in session:

  • From the client, if you wan't to force the user to log in again, you can specify prompt=login, specified in the OpenId Connect spec.
  • In your UserService implementation, there is a IsActiveAsync method. The logic there is run every time you hit the IdServer (even when the user is logged in). There you have access to the current logged in user, and may apply custom logic. Once returning false, the user will be logged out of IdServer.

There are probably other concepts that may fit you better, I'm just not sure what you are trying to achieve.

@henrikniemann
Copy link

Your scenario is actually equal to a new user borrowing the browser where you are logged in, without signing you out first, right? So IdServer knows who you are (authenticated) and logs you in to a new site. Obviously your credentials are wrong (unauthorized), so new site should send you back with a "force login". I can't decide if a check on tenant could/should be done on IdServer before actually sending you to new site?

@c0dem0nkee
Copy link
Author

Yes, you are spot on. When the new site receives the wrong credentials, it rejects it, and forces a log in. The problem is that as soon as you are redirected back to idsrv, idrsv simply passes back the already auth'ed user and then redirects back. The new site rejects the incorrect credentials and forces a login and then we get into a redirect loop.

My app has an admin section that is treated like a tenant e.g. admin.mytest.com. It is quite possible that a user will have two user accounts, one for the admin tenant and one for another tenant. It is highly probable that the user would want to be logged into both tenants at the same time but by using different user accounts.

I attempted to use the prompt=login as suggested by loctanvo which worked but required the user to re-validate their credentials every 5 minutes. This would not be ideal.

I looked into using the IsActiveSync method but that method does not have access to the SignInMessage so I cannot compare the tenant of the auth'ed user to the tenant in the acr.

Any further suggestions would be greatly received as I'm stuck at the moment

@brockallen
Copy link
Member

You can pass a tenant param via acr_values hint. This way the client tells IdSvr which tenant it's expecting. Check the docs on the authorization request.

@c0dem0nkee
Copy link
Author

Hi Brock,

I am passing the tenant via the acr. My problem is if I have authenticated on one tenant, and then attempt to authenticate on another tenant, Idsrv returns the previously auth'ed user even though its for a different tenant. This only happens if I attempt to log in to a different tenant using the same browser session.

@brockallen
Copy link
Member

Oh I think I now understand your cookie issue -- are you setting the domain on the cookie? If you don't set the domain to be the TLD then the cookie from one subdomain should not travel to the others.

@c0dem0nkee
Copy link
Author

I am not setting domains on the cookie. I don't think its an issue with the cookies on my app rather the cookie on the Idsrv app.

I have set up an idsrv app located at idsrv.mytest.com. After I have authenticated on idsrv, there are three cookies that are created called 'idsrv', 'idsrv.xsrf' and 'idsvr.session'.

If I attempt to login on to a different tenant, when I'm redirected to Idsrv and the 'idsrv' cookie exists, I simply get returned the principal in that cookie no matter what tenant I am providing in the acr.

If multi tenancy is in use, instead of having one 'idsrv' cookie, could Idsrv create cookies on a tenant by tenant basis e.g. a cookie named 'idsrv.beta' for beta tenant or 'idsrv.gamma' for the gamma tenant.

@brockallen
Copy link
Member

Ok, and so now I think I'm finally getting the picture. Your client apps are on the different host names. And they're using the one IdSvr. I misread and thought it was somehow the other way around. Sorry -- I'm thick sometimes.

So yes, I think the IsActive (that @loctanvo suggested) might be the way to go. IIRC we don't have any other hook in the authorize endpoint for you to tell IdSvr to not use the current logged in user.

@c0dem0nkee
Copy link
Author

Ok, is there a way I can inject the acr into the IsActive method? I need to compare the tenant for the signed in user to the tenant provided in the acr.

@brockallen
Copy link
Member

You'd have to inject the OWIN environment into your user service and check the param manually.

@c0dem0nkee
Copy link
Author

Okey dokey. I'll have a play and let you know my results. Cheers

@c0dem0nkee
Copy link
Author

Ok, using the prompt=login or IsActive method achieved sort of what I wanted. You can only have one signed in user at a time on a single instance of idsrv so cannot remain signed in on two tenants at the same time. Small price to pay. I'll mark this as closed

@brockallen
Copy link
Member

The OIDC spec does allow for this, we just did not implement it. Perhaps in a future iteration we could support that.

@c0dem0nkee
Copy link
Author

That would be great

@edwinf
Copy link

edwinf commented May 9, 2015

@brockallen we're looking at using IdentityServer in a new project and we have a similar requirement, has this been submitted as a feature request for consideration in future releases?

@brockallen
Copy link
Member

We're always considering... but no plans for that right now.

@edwinf
Copy link

edwinf commented May 9, 2015

Since this would be a non-starter for us, I'd be willing to try to do a PR for the functionality, if you could point me to the spec in question and if you had a rough idea how you'd like it to work, if you would be amenable to that?

@huysentruitw
Copy link

Would adding an additional subdomain to the Authority url help here?

F.e. https://tenantA.idsrv.server.com, https://tenantB.idsrv.server.com, both forwarding to the server running on https://idsrv.server.com, would this give you a idsrv cookie per domain?

@edwinf
Copy link

edwinf commented May 11, 2015

That would solve the simple case, yes; however, we have some edge cases where tennantA and tennantB are separate sites, yet authenticate to the same backend store, and they SSO to each other.

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

6 participants