Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Host several applications under the same origin #1647

Open
1 of 4 tasks
NSeydoux opened this issue Aug 30, 2021 · 7 comments
Open
1 of 4 tasks

Host several applications under the same origin #1647

NSeydoux opened this issue Aug 30, 2021 · 7 comments

Comments

@NSeydoux
Copy link
Contributor

Search terms you've used

origin

Impacted environment

In which environment would the proposed feature apply ?

  • The browser
  • Node.js
  • Other (please specify): ...
  • I'm not sure.

Feature suggestion

Allowing several applications to be served under the same origin, under different paths/with different query parameters.

Expected functionality/enhancement

Multiple applications are served under the same origin without having side effects on each other.

Actual functionality/enhancement

Currently, only one application may be hosted under a given origin. If more than one application is served under a shared origin, there are undesired behaviours especially around silent login. For instance, visiting one of the applications will automatically trigger a login involving a redirection to the latest application the user has logged in for the given origin, rather than simply keeping the user logged out until they initiate login.

Use Cases

  • Using personal GitHub pages to serve applications from several repositories.

Additional information

This feature has been requested as part of the conversation in #1473, see additional details there.

@jeff-zucker
Copy link

This is biting us pretty hard with the stand-alone webapp for the databrowser. It would be great to have the ability to run several apps from the same origin.

@NSeydoux
Copy link
Contributor Author

Unfortunately, this would require non-trivial changes to the library, and it isn't on our short-term roadmap. I'll think about the design changes this entails though, and keep this issue updated accordingly.

@angelo-v
Copy link

angelo-v commented Feb 9, 2022

This problem also affects hosting html apps on Solid Pods! (like hosting an app as index.html within a container on a pod)

In practice this e.g. is problematic for my solid-groups app which is meant to be hosted on a Pod side-by-side with e.g. SolidOS.

If I upgraded it to use solid-client-authn-js right now, the redirects would break, so users either would always be redirected to the solid-groups app, or SolidOS, depending on where they logged in the first time they visited.

This is a real show stopper and I hope Inrupt will give it some more attention.

I guess that the really great apps from @NoelDeMartin are also affected, since e.g. https://noeldemartin.github.io/solid-focus/ and https://noeldemartin.github.io/media-kraken/ share a domain.

@NoelDeMartin
Copy link

Hey @angelo-v thanks for mentioning it.

Yes, I'm aware of this issue, but I've suffered from this in my own apps not only because of authentication libraries, but with my own use of localStorage. For that reason, I'm not going to publish any more apps like that and I'll use a subdomain on my site. I'm not aware of any workarounds other than prefixing the storage key names... I don't need to do it because I won't serve multiple apps on the same domain again, but I'm not sure how easy it would be for Inrupt's library to add a configuration option to change this.

I also haven't updated solid-focus to use the new authentication yet, so this is not an issue for me at the moment. But I have plans to move both apps to solid-focus.noeldemartin.com and media-kraken.noeldemartin.com respectively (those urls don't work yet).

@angelo-v
Copy link

angelo-v commented Feb 16, 2022

Another use case the current behaviour is blocking: Traditional multi-page apps that do full page reloads on navigation.

I am currently working on solid web components, and imagined those could be used to bring solid functionality to traditional web pages. Let's say adding a like button or a comment section to a wordpress blog post. This will not work, because as soon I log in on post A i am always redirected to that one, even if I am currently on post B and signing in to leave a comment there.

I wonder if this could be solved by forcing a fresh dynamic-client registration on each page. Currently all pages would re-use existing client regisration and it's (single) redirect url. Is there a way to have a different client on each page @NSeydoux?

Unfortunately, this would require non-trivial changes to the library, and it isn't on our short-term roadmap. I'll think about the design changes this entails though, and keep this issue updated accordingly.

If you share your thoughts on that, I am willing to help out, since it is really blocking several of my Solid ideas.

@NSeydoux
Copy link
Contributor Author

I think one of the main issues here, as pointed out by @NoelDeMartin, is that the browser shares some resources for a given origin, such as localStorage. We are currently looking at how we are using localStorage in solid-client-authn-browser, and I'm keeping this issue in mind doing so. One of the things making resolving this non-trivial is that we are depending on a third-party library to handle part of the OIDC flow (namely https://github.com/inrupt/oidc-client-js, which we forked for maintenance reasons), which also relies on storing things in local storage. Changing this library behaviour requires some additional work, as it's not a codebase we're very familiar with.

The silent login flow has also been mentioned as being problematic in this context. To summarize, no browser API can be relied on securely to store sensitive information (as mentioned in a related recent forum thread), which means auth-related pieces of data such as the ID of access tokens cannot be stored elsewhere than in memory. Consequently, upon refresh or navigation to a different page, the tokens are lost. However, the browser may have a cookie set by the user's OIDC Provider. If their session is still active, logging the user back in does not require any interaction, the browser is redirected to and from the OIDC provider instantly. For this to work though, the client must have the user's consent, which means in particular in the case of dynamically registered clients that the client must be exactly "the same" when doing silent login. And being "the same" includes having the same redirect IRI as during the initial user login. This the reason why the problematic behaviour is observed: from the client point of view, it's challenging to tell whether

  • the user has been through client-side navigation, and refreshed a page which isn't the one they originally logged into, in which case the desired behaviour is to do silent login, redirect the user to the original page, and there have the client-side navigation complete the redirection to the page which was just refreshed (as described in our documentation)
  • or the user is visiting a different app hosted under the same origin as another app they had previously logged into and didn't log out from, in which case the silent login is undesired.

I haven't tested it, but I suspect not enabling silent login (leaving restorePreviousSession to false calling handleIncomingRedirect) should help serving two apps under the same origin, because then as you describe @angelo-v client registration should be renewed each time. However, the UX would not be ideal because you'd have to log in manually each time.

Using client identifiers instead of dynamic authentication may probably also be helpful, because in this case it is explicit which client the user intends to log into, which I think should solve the ambiguity I described above.

Does it clarify the reasons we are having this issue, and possible steps to mitigate it ?

@josephguillaume
Copy link

I'm not yet sure how to make a reproducible example, but by using overrides in Chrome, I've managed to establish that it is possible for a static client hosted on the pod using a client identifier to log in without interfering with solidos (which uses dynamic registration).

  1. I first logged in normally on the static client to establish a session on the IDP using that client identifier
  2. I then logged in on solidos. As documented in this issue, this overwrites the session in localStorage
  3. I then logged in automatically on the static client by manually overriding the call to use prompt=none (as is done usually by restorePreviousSession)

So far so good. A static client doesn't actually need the stored session - all it needs is the URL of the IDP and its client identifier. With prompt=none, the IDP then allows login with its existing cookie.

However, the static client still overwrites the session in localStorage, so SolidOS is logged out.
To avoid this, I needed to add overrides to comment out (in the bundle):

  • await this.sessionInfoManager.clear(t.sessionId);
  • this.on(r.EVENTS.LOGIN, (()=>window.localStorage.setItem(o.KEY_CURRENT_SESSION, this.info.sessionId))),

It therefore appears that a partial fix for this issue that enables multiple static clients on one domain would involve differentiating handling of the stored session info for static clients, only storing between sessions the IDP and an indication of logged in status (an error is raised if prompt=none is specified without being logged in).

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

No branches or pull requests

5 participants