-
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
Implement Server-Side sessions #68117
Changes from 44 commits
bfd42f0
fc0ab5d
194b06e
176fe3b
3f85d63
50a09bb
ada2b9f
a30e49b
f033f72
38f15bb
959a535
9d3273b
7133991
e915c3f
21bb805
11b3c4e
8bd08e5
3fe0d46
ccbcec1
04801a1
b6f3987
3f1fa9c
b91f050
09acb02
38f41cf
e98dbd0
a86884c
6acf005
d518e99
a8d46f1
d3c8454
bcbd9c2
fb47b91
b40adf6
9548184
f03d978
2d3ea32
8ee6b90
21d24ed
efdbef2
92437c0
d69116a
ed6944d
ca64e87
4d0ee0d
378c239
a4cdb60
b178201
3ded572
5bc9502
1d27f02
8ea6939
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -125,8 +125,8 @@ In addition to <<authentication-provider-settings,the settings that are valid fo | |||||
| SAML realm in {es} that provider should use. | ||||||
|
||||||
| `xpack.security.authc.providers.` | ||||||
`saml.<provider-name>.maxRedirectURLSize` | ||||||
| The maximum size of the URL that {kib} is allowed to store during the authentication SAML handshake. For more information, refer to <<security-saml-and-long-urls>>. | ||||||
`saml.<provider-name>.useRelayStateDeepLink` | ||||||
| Determines if provider should treat `RelayState` parameter as a deep link in {kib} during Identity Provider initiated login. By default, this setting is set to `false`. The link specified in `RelayState` should be a relative, URL-encoded {kib} URL, e.g. for `/app/dashboards#/list` link `RelayState` parameter would look like this `RelayState=%2Fapp%2Fdashboards%23%2Flist` for . | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
|=== | ||||||
|
||||||
|
@@ -186,8 +186,7 @@ You can configure the following settings in the `kibana.yml` file. | |||||
| Sets the name of the cookie used for the session. The default value is `"sid"`. | ||||||
|
||||||
| `xpack.security.encryptionKey` | ||||||
| An arbitrary string of 32 characters or more that is used to encrypt credentials | ||||||
in a cookie. It is crucial that this key is not exposed to users of {kib}. By | ||||||
| An arbitrary string of 32 characters or more that is used to encrypt session information. It is crucial that this key is not exposed to users of {kib}. By | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
default, a value is automatically generated in memory. If you use that default | ||||||
behavior, all sessions are invalidated when {kib} restarts. | ||||||
In addition, high-availability deployments of {kib} will behave unexpectedly | ||||||
|
@@ -237,6 +236,20 @@ string of `<count>[ms|s|m|h|d|w|M|Y]` (e.g. '70ms', '5s', '3d', '1Y'). | |||||
[cols="2*<"] | ||||||
|=== | ||||||
|
||||||
| `xpack.security.session.cleanupInterval` | ||||||
| Sets the interval at which {kib} tries to remove expired and invalid sessions from the session index. By default, this value is 1 hour. The minimum value is 10 seconds. | ||||||
|
||||||
|=== | ||||||
|
||||||
[TIP] | ||||||
============ | ||||||
The format is a | ||||||
string of `<count>[ms|s|m|h|d|w|M|Y]` (e.g. '20m', '24h', '7d', '1w'). | ||||||
============ | ||||||
|
||||||
[cols="2*<"] | ||||||
|=== | ||||||
|
||||||
| `xpack.security.loginAssistanceMessage` | ||||||
| Adds a message to the login screen. Useful for displaying information about maintenance windows, links to corporate sign up pages etc. | ||||||
|
||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,62 @@ | ||||||
[role="xpack"] | ||||||
[[xpack-security-session-management]] | ||||||
=== Session management | ||||||
|
||||||
When you log in to {kib} it creates a session that is used to authenticate any subsequent request to {kib} made on your behalf. {kib} encrypts any sensitive session information and stores it in a dedicated hidden {es} index. By default, the name of that index is `.kibana_security_session_1` where the prefix depends on the name of the main `.kibana` index. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
Additionally, for every new session {kib} creates an encrypted client side cookie that is stored in your browser and sent to {kib} with every request. This way {kib} can associate request with the session information stored in the session index. | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
When your session expires, or you log out of {kib} explicitly it will invalidate your cookie and remove session information from the index. In addition to that {kib} performs a regular session index cleanup to remove any expired sessions that weren't invalidated explicitly. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
[[session-idle-timeout]] | ||||||
==== Session idle timeout | ||||||
|
||||||
You can configure timeout to expire idle sessions. By default, a session stays | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
active until the browser is closed. To define a sliding session expiration, set | ||||||
the `xpack.security.session.idleTimeout` property in the `kibana.yml` | ||||||
configuration file. The idle timeout is formatted as a duration of | ||||||
`<count>[ms|s|m|h|d|w|M|Y]` (e.g. '70ms', '5s', '3d', '1Y'). For example, set | ||||||
the idle timeout to expire idle sessions after 10 minutes: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
-- | ||||||
[source,yaml] | ||||||
-------------------------------------------------------------------------------- | ||||||
xpack.security.session.idleTimeout: "10m" | ||||||
-------------------------------------------------------------------------------- | ||||||
-- | ||||||
|
||||||
[[session-lifespan]] | ||||||
==== Session lifespan | ||||||
|
||||||
You can configure the maximum session duration or "lifespan" -- also known as | ||||||
the "absolute timeout". By default, a session stays active until the browser is | ||||||
closed. If an idle timeout is defined, a session can still be extended | ||||||
indefinitely. To define a maximum session lifespan, set the | ||||||
`xpack.security.session.lifespan` property in the `kibana.yml` configuration | ||||||
file. The lifespan is formatted as a duration of `<count>[ms|s|m|h|d|w|M|Y]` | ||||||
(e.g. '70ms', '5s', '3d', '1Y'). For example, set the lifespan to expire | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd suggest changing this to match the new description in my top-level comment, if you agree with it. |
||||||
sessions after 8 hours: | ||||||
|
||||||
-- | ||||||
[source,yaml] | ||||||
-------------------------------------------------------------------------------- | ||||||
xpack.security.session.lifespan: "8h" | ||||||
-------------------------------------------------------------------------------- | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about changing this example to use our planned default of 30 days? |
||||||
-- | ||||||
|
||||||
[[session-cleanup-interval]] | ||||||
==== Session cleanup interval | ||||||
|
||||||
You can configure the interval at which {kib} tries to remove expired and invalid sessions from the session index. By default, this value is 1 hour and cannot be less than 10 seconds. To define another interval, set the `xpack.security.session.cleanupInterval` property in the `kibana.yml` configuration file. The interval is formatted as a duration of `<count>[ms|s|m|h|d|w|M|Y]` (e.g. '70000ms', '50s', '3d', '1Y'). For example, schedule session index cleanup to be performed only once a day: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
-- | ||||||
[source,yaml] | ||||||
-------------------------------------------------------------------------------- | ||||||
xpack.security.session.cleanupInterval: "1d" | ||||||
-------------------------------------------------------------------------------- | ||||||
-- | ||||||
|
||||||
[IMPORTANT] | ||||||
============================================================================ | ||||||
If you specify neither session idle timeout nor lifespan, then {kib} will not automatically remove session information from the index unless you explicitly log out of {kib}. This may lead to an infinitely growing session index. It's one of the reasons why we strongly recommend configuring idle timeout and lifespan settings for the {kib} sessions so that they can be eventually cleaned up even if you don't log out of {kib} explicitly. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@gchaps It seems There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh you're right. Ignore my edit then. |
||||||
============================================================================ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like this admonition should not be at the bottom of the page. Edit: as in, perhaps it should be moved up higher / displayed more prominently. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { AppMount, ScopedHistory } from 'src/core/public'; | ||
import { captureURLApp } from './capture_url_app'; | ||
|
||
import { coreMock, scopedHistoryMock } from '../../../../../../src/core/public/mocks'; | ||
|
||
describe('captureURLApp', () => { | ||
beforeAll(() => { | ||
Object.defineProperty(window, 'location', { | ||
value: { href: 'https://some-host' }, | ||
writable: true, | ||
}); | ||
}); | ||
|
||
it('properly registers application', () => { | ||
const coreSetupMock = coreMock.createSetup(); | ||
|
||
captureURLApp.create(coreSetupMock); | ||
|
||
expect(coreSetupMock.http.anonymousPaths.register).toHaveBeenCalledTimes(1); | ||
expect(coreSetupMock.http.anonymousPaths.register).toHaveBeenCalledWith( | ||
'/internal/security/capture-url' | ||
); | ||
|
||
expect(coreSetupMock.application.register).toHaveBeenCalledTimes(1); | ||
|
||
const [[appRegistration]] = coreSetupMock.application.register.mock.calls; | ||
expect(appRegistration).toEqual({ | ||
id: 'security_capture_url', | ||
chromeless: true, | ||
appRoute: '/internal/security/capture-url', | ||
title: 'Capture URL', | ||
mount: expect.any(Function), | ||
}); | ||
}); | ||
|
||
it('properly handles captured URL', async () => { | ||
window.location.href = `https://host.com/mock-base-path/internal/security/capture-url?next=${encodeURIComponent( | ||
'/mock-base-path/app/home' | ||
)}&providerType=saml&providerName=saml1#/?_g=()`; | ||
|
||
const coreSetupMock = coreMock.createSetup(); | ||
coreSetupMock.http.post.mockResolvedValue({ location: '/mock-base-path/app/home#/?_g=()' }); | ||
|
||
captureURLApp.create(coreSetupMock); | ||
|
||
const [[{ mount }]] = coreSetupMock.application.register.mock.calls; | ||
await (mount as AppMount)({ | ||
element: document.createElement('div'), | ||
appBasePath: '', | ||
onAppLeave: jest.fn(), | ||
history: (scopedHistoryMock.create() as unknown) as ScopedHistory, | ||
}); | ||
|
||
expect(coreSetupMock.http.post).toHaveBeenCalledTimes(1); | ||
expect(coreSetupMock.http.post).toHaveBeenCalledWith('/internal/security/login', { | ||
body: JSON.stringify({ | ||
providerType: 'saml', | ||
providerName: 'saml1', | ||
currentURL: `https://host.com/mock-base-path/internal/security/capture-url?next=${encodeURIComponent( | ||
'/mock-base-path/app/home' | ||
)}&providerType=saml&providerName=saml1#/?_g=()`, | ||
}), | ||
}); | ||
|
||
expect(window.location.href).toBe('/mock-base-path/app/home#/?_g=()'); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence ends with "for ." Did you mean to add something else?