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

Add OpenID Connect auth provider #36201

Merged
merged 31 commits into from
May 21, 2019
Merged

Conversation

jkakavas
Copy link
Member

@jkakavas jkakavas commented May 7, 2019

Summary

The OpenID Connect authProvider is the accompanying authProvider for the OpenID Connect authentication realm in Elasticsearch. This is very similar to the saml authProvider in most ways with three noticeable differences:

  • We require explicit configuration regarding the Elasticsearch realm name instead of trying to build an environment aware string (like ACS URL in saml) and pass that to Elasticsearch for it to resolve the realm.
  • We do not support multiple values for the realm specific nonces (state and nonce) as we do with requestId in the SAML realm. Instead if an existing value ( for state and nonce) is present in the user's session, we pass that to Elasticsearch to be reused. The end goal is the same, allow a better UX for users attempting many requests over different tabs in the same browser context.
  • IDP initiated SSO ( Third Party initiated authentication in OIDC-speak ) is implemented but starts as an unsolicited request to initiate the handshake, instead of an unsolicited request with an authentication response (which is not supported here)

This change also adds a fake plugin named oidc_provider to be used in integration tests for mocking calls to the token and userinfo endpoint of an OpenID Connect Provider

Missing:

  • Documentation

Limitations

This does not support the OpenID Connect Implicit flow as that depends on fragment handling/processing as described for instance in the spec

Co-Authored-By: Brandon Kobel kobelb@elastic.co

"Release Note: Added support for authenticating using OpenID Connect"

Contrary to what happens in the SAML realm, we do not support
consuming unsolicited Responses from OpenID Connect Providers. This
means that the only way that a behavior such as the one described in
 elastic#33644 can be observed is when
 - a user initiates a login in a tab but stalls in the OP
   authentication form
 - user opens a new tab in the same browser and completes
   authentication
 - user returns to original tab, submits the OP form and lands in
   Kibana's oidc endpoint while actually already having a session.

Not sure if this is a corner case we need to cater for, so removing
this for now.
- Add a fake plugin, used to mock the token endpoint and userinfo
  endpoint of an OpenID Connect Provider
- Add various integration tests for the OIDC auth provider
@jkakavas jkakavas added review Team:Security Team focused on: Auth, Users, Roles, Spaces, Audit Logging, and more! labels May 7, 2019
@jkakavas jkakavas requested review from kobelb and azasypkin May 7, 2019 15:47
@jkakavas jkakavas requested a review from a team as a code owner May 7, 2019 15:47
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-security

@jkakavas jkakavas mentioned this pull request May 7, 2019
7 tasks
@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@azasypkin
Copy link
Member

Looks like you need to run node scripts/eslint --fix to automatically fix all linter issues.

@elasticmachine
Copy link
Contributor

💔 Build Failed

@azasypkin
Copy link
Member

09:51:48 plugins/security/server/lib/authentication/providers/oidc.ts:8:24 - error TS2307: Cannot find module '../../../../../../../kibana'.
09:51:48 8 import { Legacy } from '../../../../../../../kibana';

Relative paths from x-pack to OSS aren't yet supported in the prod build, so you'd need to use kibana alias instead: import { Legacy } from 'kibana';

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@azasypkin
Copy link
Member

ACK: will take a look tomorrow, I'll skip integration tests for now, but will review them as soon as we solve this nasty CI & server.xsrf.whitelist weirdness.

@jkakavas
Copy link
Member Author

This fails because

00:29:18 plugins/security/server/lib/authentication/authenticator.ts:34:3 - error TS2345: Argument of type '([string, typeof BasicAuthenticationProvider] | [string, typeof SAMLAuthenticationProvider] | [string, typeof TokenAuthenticationProvider] | [string, typeof OIDCAuthenticationProvider])[]' is not assignable to parameter of type 'ReadonlyArray<[string, new (options: AuthenticationProviderOptions) => BaseAuthenticationProvider<AuthenticationProviderOptions>]>'.
00:29:18   Type '[string, typeof BasicAuthenticationProvider] | [string, typeof SAMLAuthenticationProvider] | [string, typeof TokenAuthenticationProvider] | [string, typeof OIDCAuthenticationProvider]' is not assignable to type '[string, new (options: AuthenticationProviderOptions) => BaseAuthenticationProvider<AuthenticationProviderOptions>]'.
00:29:18     Type '[string, typeof OIDCAuthenticationProvider]' is not assignable to type '[string, new (options: AuthenticationProviderOptions) => BaseAuthenticationProvider<AuthenticationProviderOptions>]'.
00:29:18       Type 'typeof OIDCAuthenticationProvider' is not assignable to type 'new (options: AuthenticationProviderOptions) => BaseAuthenticationProvider<AuthenticationProviderOptions>'.
00:29:18         Types of parameters 'options' and 'options' are incompatible.
00:29:18           Property 'realm' is missing in type 'AuthenticationProviderOptions' but required in type 'OIDCProviderOptions'.
00:29:18 
00:29:18  34 >([
00:29:18       ~
00:29:18  35   ['basic', BasicAuthenticationProvider],
00:29:18     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00:29:18 ... 
00:29:18  38   ['oidc', OIDCAuthenticationProvider],
00:29:18     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00:29:18  39 ]);
00:29:18     ~
00:29:18 
00:29:18   plugins/security/server/lib/authentication/providers/oidc.ts:71:3
00:29:18     71   realm: string;
00:29:18          ~~~~~
00:29:18     'realm' is declared here.
00:29:18 
00:29:18 
00:29:18 Found 1 error.

if I make the realm parameter optional in the authProvider , i.e.

/**
 * Defines the realm specific properties
 */
interface OIDCProviderOptions extends AuthenticationProviderOptions {
  realm?: string;
}

then calling something like

return this.initiateOIDCAuthentication(request, { realm: this.options.realm });

also fails as this.options.realm can be string or undefined.

Any suggestions on what is the proper way to handle this @azasypkin ?

@azasypkin
Copy link
Member

Hey @jkakavas!

I'll be off next week and won't be able to do the second review pass till May 27th. If it can't wait till then, please, feel free to forward review request to someone else on @elastic/kibana-security team.

@jkakavas
Copy link
Member Author

Understood @azasypkin , I hope Brandon or Larry can lend a pair of eyes over the next few days !

@kobelb
Copy link
Contributor

kobelb commented May 20, 2019

@jkakavas I'll take a look a bit later today.

@jkakavas jkakavas requested a review from legrego May 20, 2019 15:06
@kobelb
Copy link
Contributor

kobelb commented May 20, 2019

@kobelb do you remember why we made LoginAttempt tightly coupled to basic/token auth provider (depends on username and password)? I thought we could use it for SAML or OIDC login attempts as well to not rely just on query string or payload parameter names.

Based on #25431 (comment), this is something that you recommended initially but we held off on doing so because we wanted to see if this was a commonality between all SSO providers.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@jkakavas jkakavas merged commit e569fba into elastic:master May 21, 2019
legrego pushed a commit to legrego/kibana that referenced this pull request May 21, 2019
The OpenID Connect authProvider is the accompanying authProvider for the OpenID Connect authentication realm in Elasticsearch. This is very similar to the saml authProvider in most ways with three noticeable differences:

- We require explicit configuration regarding the Elasticsearch realm name instead of trying to build an environment aware string (like ACS URL in saml) and pass that to Elasticsearch for it to resolve the realm.
- We do not support multiple values for the realm specific nonces (state and nonce) as we do with requestId in the SAML realm. Instead if an existing value ( for state and nonce) is present in the user's session, we pass that to Elasticsearch to be reused. The end goal is the same, allow a better UX for users attempting many requests over different tabs in the same browser context.
- IDP initiated SSO ( Third Party initiated authentication in OIDC-speak ) is implemented but starts as an unsolicited request to initiate the handshake, instead of an unsolicited request with an authentication response (which is not supported here)

This change also adds a fake plugin named oidc_provider to be used in integration tests for mocking calls to the token and userinfo endpoint of an OpenID Connect Provider

This does not support the OpenID Connect Implicit flow as that depends on fragment handling/processing as described for instance in the spec

Co-Authored-By: Brandon Kobel <kobelb@elastic.co>
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

kobelb pushed a commit to kobelb/kibana that referenced this pull request May 21, 2019
The OpenID Connect authProvider is the accompanying authProvider for the OpenID Connect authentication realm in Elasticsearch. This is very similar to the saml authProvider in most ways with three noticeable differences:

- We require explicit configuration regarding the Elasticsearch realm name instead of trying to build an environment aware string (like ACS URL in saml) and pass that to Elasticsearch for it to resolve the realm.
- We do not support multiple values for the realm specific nonces (state and nonce) as we do with requestId in the SAML realm. Instead if an existing value ( for state and nonce) is present in the user's session, we pass that to Elasticsearch to be reused. The end goal is the same, allow a better UX for users attempting many requests over different tabs in the same browser context.
- IDP initiated SSO ( Third Party initiated authentication in OIDC-speak ) is implemented but starts as an unsolicited request to initiate the handshake, instead of an unsolicited request with an authentication response (which is not supported here)

This change also adds a fake plugin named oidc_provider to be used in integration tests for mocking calls to the token and userinfo endpoint of an OpenID Connect Provider

This does not support the OpenID Connect Implicit flow as that depends on fragment handling/processing as described for instance in the spec

Co-Authored-By: Brandon Kobel <kobelb@elastic.co>
legrego pushed a commit that referenced this pull request May 22, 2019
The OpenID Connect authProvider is the accompanying authProvider for the OpenID Connect authentication realm in Elasticsearch. This is very similar to the saml authProvider in most ways with three noticeable differences:

- We require explicit configuration regarding the Elasticsearch realm name instead of trying to build an environment aware string (like ACS URL in saml) and pass that to Elasticsearch for it to resolve the realm.
- We do not support multiple values for the realm specific nonces (state and nonce) as we do with requestId in the SAML realm. Instead if an existing value ( for state and nonce) is present in the user's session, we pass that to Elasticsearch to be reused. The end goal is the same, allow a better UX for users attempting many requests over different tabs in the same browser context.
- IDP initiated SSO ( Third Party initiated authentication in OIDC-speak ) is implemented but starts as an unsolicited request to initiate the handshake, instead of an unsolicited request with an authentication response (which is not supported here)

This change also adds a fake plugin named oidc_provider to be used in integration tests for mocking calls to the token and userinfo endpoint of an OpenID Connect Provider

This does not support the OpenID Connect Implicit flow as that depends on fragment handling/processing as described for instance in the spec

Co-Authored-By: Brandon Kobel <kobelb@elastic.co>
@legrego legrego mentioned this pull request Jun 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release_note:enhancement Team:Security Team focused on: Auth, Users, Roles, Spaces, Audit Logging, and more! v7.2.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants