-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
[Discuss] A way for plugins to store and retrieve their own data from the server side session #92558
Comments
Pinging @elastic/kibana-security (Team:Security) |
ping @ioanatia @jportner @azasypkin |
The ability to store custom data in a user session sounds reasonable to me in general. I think it can be useful for other plugins in the future too. Here is just a very rough idea on how that could look like, please comment if you have any concerns, or questions, or ideas. ////// -----------SETUP-----------
// To avoid name collisions and prevent other plugins from accessing values they don't own you have
// to register a session storage container with a unique name at the `SETUP` stage. Container name will
// be used as a prefix for all session storage values your plugin is going to deal with. You're not allowed
// and don't have a way to retrieve or store any values in the session at this stage.
// @returns Session storage container instance that you can exchange to a session storage in `START`.
// @throws If this method is invoked after `setup` or if any other plugin already registered session storage
// container with such a name error will be thrown.
const sessionStorageContainer = setupDeps.security.sessionStorage.registerContainer(
'xpack.entSearch'
);
////// -----------START-----------
// Then at the `START` stage you can retrieve a session storage that is bound to a particular container.
// @returns Session storage that can be used to store or retrieve session values.
// @throws If container isn't valid for whatever reason this method will throw.
const sessionStorage = startDeps.security.sessionStorage.getStorage(sessionStorageContainer);
////// -----------USER REQUEST-----------
// Method is asynchronous as it may cause a request to Elasticsearch.
// @returns Returns value in the same form as it was stored (deserialized).
// @throws Method doesn't swallow any exceptions, consumers should handle errors on their own,
// e.g. when Elasticsearch isn't available or if request isn't authenticated.
const value = await sessionStorage.get(request, 'my-key');
// Method is asynchronous as it causes request to Elasticsearch to persist a session value.
// @throws Method doesn't swallow any exceptions, consumers should handle errors on their own,
// e.g. when Elasticsearch isn't available or request isn't authenticated. In addition to that consumers
// should make sure that `value` is JSON serializable.
await sessionStorage.set(request, 'my-key', value);
// Method is asynchronous as it causes request to Elasticsearch to persist a session value.
// @throws Method doesn't swallow any exceptions, consumers should handle errors on their own, e.g. when
// Elasticsearch isn't available or if request isn't authenticated.
await sessionStorage.remove(request, 'my-key'); Sessions are retrieved from Elasticsearch on every request and I assume the values that plugins will store will have to be encrypted/decrypted. So the size of the session content is critical. If Security plugin notices a very large value, it may issue a @jgr when do you need this? Do you have a workaround that you're happy with for the time being? |
@azasypkin I'm still confirming a few things, but overall this looks great! It should satisfy the need we have.
This makes sense to me. I'm working now to only send what we need for the current OAuth flow, rather than the entire session. I can figure out the size of the maximum payload we'll be storing, if you're curious. I'm currently encrypting/decrypting it on the Enterprise Search side.
We should be able to remove these values while processing a successful source connection 👍
We're aiming to have our Kibana plugin usable stand alone in 7.14. It would be nice to have it by then.
I should know this by the end of the week. I'm proving out a workaround we've been discussing. I may ask for suggestions if I run into further problems using a cookie. |
Yes, please share when you have the numbers. We'd like to better understand the needs of the consumers of this API.
Good, 7.14 sounds doable to me.
Got it, let us know if you're stuck with anything. |
This modifies the EnterpriseSearchRequestHandler to remove any data in a response under the _sessionData key and instead persist it on the server side. Ultimately, this data will be persisted in the login session, but for now we'll just store it in a cookie. elastic#92558 Also uses this functionality to persist Workplace Search's OAuth token package.
This modifies the EnterpriseSearchRequestHandler to remove any data in a response under the _sessionData key and instead persist it on the server side. Ultimately, this data will be persisted in the login session, but for now we'll just store it in a cookie. elastic#92558 Also uses this functionality to persist Workplace Search's OAuth token package.
…low (#93210) * Store session data sent from Enterprise Search server This modifies the EnterpriseSearchRequestHandler to remove any data in a response under the _sessionData key and instead persist it on the server side. Ultimately, this data will be persisted in the login session, but for now we'll just store it in a cookie. #92558 Also uses this functionality to persist Workplace Search's OAuth token package. * Only return a modified response body if _sessionData was found The destructuring I'm doing to remove _sessionData from the response is breaking routes that currently expect an empty response body. This change just leaves those response bodies alone. * Refactor from initial feedback & add tests * Decrease levity * Changes from PR feedback Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
…low (elastic#93210) * Store session data sent from Enterprise Search server This modifies the EnterpriseSearchRequestHandler to remove any data in a response under the _sessionData key and instead persist it on the server side. Ultimately, this data will be persisted in the login session, but for now we'll just store it in a cookie. elastic#92558 Also uses this functionality to persist Workplace Search's OAuth token package. * Only return a modified response body if _sessionData was found The destructuring I'm doing to remove _sessionData from the response is breaking routes that currently expect an empty response body. This change just leaves those response bodies alone. * Refactor from initial feedback & add tests * Decrease levity * Changes from PR feedback Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
…low (#93210) (#94030) * Store session data sent from Enterprise Search server This modifies the EnterpriseSearchRequestHandler to remove any data in a response under the _sessionData key and instead persist it on the server side. Ultimately, this data will be persisted in the login session, but for now we'll just store it in a cookie. #92558 Also uses this functionality to persist Workplace Search's OAuth token package. * Only return a modified response body if _sessionData was found The destructuring I'm doing to remove _sessionData from the response is breaking routes that currently expect an empty response body. This change just leaves those response bodies alone. * Refactor from initial feedback & add tests * Decrease levity * Changes from PR feedback Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: James Rucker <james.rucker@elastic.co>
An update: we have a workaround that we're comfortable with (using a cookie) and it is nearly complete. I also spent some time generating payloads. I believe the largest string we would store is 789 characters. Here is an example:
|
Looks good, thanks for the update 👍 |
@jgr, while working on #98049 I realized that there is one limitation that you'll hit if you start storing your data in the user session: We don't maintain sessions for the users who're authenticated via I doubt that such setups are used with the Workplace Search though, but I wanted to call it out anyway. |
@azasypkin thanks for pointing that out. While I'm not familiar with this technique to emulate anonymous access, I agree that it seems unlikely that it will effect users of Enterprise Search. |
Good, thanks for confirming. For the sake of completeness, emulating of the anonymous access is just one example, our users rely on reverse proxies + Kibana HTTP authentication for other cases too, e.g. custom authentication via |
It doesn't seem there is enough demand to warrant this change, closing for now. |
Kibana recently moved to using a server-side session store. We (the Workplace Search team) would like a way to store plugin specific data in this server side session so that it follows the user throughout their login session.
Background
In the course of setting up the product operators go through the OAuth flows of third party services to connect them to Workplace Search. While an operator is going through these flows the Workplace Search product currently saves some temporary tokens and an authenticity token in it's own login session. As we transition this functionality to the Enterprise Search plugin we'd like to store these tokens in Kibana's session instead, as we do not maintain an Enterprise Search session when using the product via the Kibana plugin.
Something as durable as a login session store is preferable because these tokens need to persist between a redirect. As part of the OAuth flow the plugin redirects the user to the third party to be authenticated, and the third party redirects the user back to the Kibana plugin.
An Example
I'm envisioning something fairly simple that takes a
KibanaRequest
(to find the session), a key to set in the session, and a string payload. Something along the lines of:Retrieval would be fairly similar.
I realize we might need to do more here to scope this to just a single plugin, but hopefully that example illustrates our need.
I also realize that there could be a session when there is no user logged in. This isn't really a use case for Workplace Search (as our plugin only really makes sense when a user is authenticated and has the appropriate access), but I understand I may need to guard these calls with a check that there is a currently logged in user.
The text was updated successfully, but these errors were encountered: