mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[6.8] Allow SAML IdP initiated login when SAML authentication provider is NOT configured as the first provider. (#60240)
This commit is contained in:
parent
34147e8f79
commit
dc91d17ffc
8 changed files with 509 additions and 12 deletions
|
@ -134,7 +134,7 @@ class Authenticator {
|
|||
const existingSession = await this._session.get(request);
|
||||
|
||||
let authenticationResult;
|
||||
for (const [providerType, provider] of this._providerIterator(existingSession)) {
|
||||
for (const [providerType, provider] of this._providerIterator(existingSession, request)) {
|
||||
// Check if current session has been set by this provider.
|
||||
const ownsSession = existingSession && existingSession.provider === providerType;
|
||||
|
||||
|
@ -208,7 +208,7 @@ class Authenticator {
|
|||
// SP associated with the current user session to do the logout. So if Kibana (without active session)
|
||||
// receives such a request it shouldn't redirect user to the home page, but rather redirect back to IdP
|
||||
// with correct logout response and only Elasticsearch knows how to do that.
|
||||
if (request.query.SAMLRequest && this._providers.has('saml')) {
|
||||
if (this._isSAMLRequest(request) && this._providers.has('saml')) {
|
||||
return this._providers.get('saml').deauthenticate(request);
|
||||
}
|
||||
|
||||
|
@ -234,19 +234,22 @@ class Authenticator {
|
|||
/**
|
||||
* Returns provider iterator where providers are sorted in the order of priority (based on the session ownership).
|
||||
* @param {Object} sessionValue Current session value.
|
||||
* @param {Hapi.Request} request HapiJS request instance.
|
||||
* @returns {Iterator.<Object>}
|
||||
*/
|
||||
*_providerIterator(sessionValue) {
|
||||
// If there is no session to predict which provider to use first, let's use the order
|
||||
// providers are configured in. Otherwise return provider that owns session first, and only then the rest
|
||||
// of providers.
|
||||
if (!sessionValue) {
|
||||
*_providerIterator(sessionValue, request) {
|
||||
// If there is no way to predict which provider to use first, let's use the order providers are configured in.
|
||||
// Otherwise return provider that either owns session or can handle 3rd-party login request first, and only then
|
||||
// the rest of providers.
|
||||
const shouldHandleSAMLResponse = this._isSAMLResponse(request) && this._providers.has('saml');
|
||||
if (!sessionValue && !shouldHandleSAMLResponse) {
|
||||
yield* this._providers;
|
||||
} else {
|
||||
yield [sessionValue.provider, this._providers.get(sessionValue.provider)];
|
||||
const provider = shouldHandleSAMLResponse ? 'saml' : sessionValue.provider;
|
||||
yield [provider, this._providers.get(provider)];
|
||||
|
||||
for (const [providerType, provider] of this._providers) {
|
||||
if (providerType !== sessionValue.provider) {
|
||||
if (providerType !== provider) {
|
||||
yield [providerType, provider];
|
||||
}
|
||||
}
|
||||
|
@ -273,6 +276,27 @@ class Authenticator {
|
|||
|
||||
return sessionValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether specified request represents SAML Request.
|
||||
* @param {Hapi.Request} request HapiJS request instance.
|
||||
* @returns {boolean}
|
||||
* @private
|
||||
*/
|
||||
_isSAMLRequest(request) {
|
||||
return !!(request.query && request.query.SAMLRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether specified request represents SAML Response.
|
||||
* @param {Hapi.Request} request HapiJS request instance.
|
||||
* @returns {boolean}
|
||||
* @private
|
||||
*/
|
||||
_isSAMLResponse(request) {
|
||||
return !!(request.payload && request.payload.SAMLResponse)
|
||||
&& request.path === '/api/security/v1/saml';
|
||||
}
|
||||
}
|
||||
|
||||
export async function initAuthenticator(server, authorizationMode) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue