Migrate authentication functionality to a new Elasticsearch client.#87094
Migrate authentication functionality to a new Elasticsearch client.#87094azasypkin merged 5 commits intoelastic:masterfrom
Conversation
c587775 to
a585f9c
Compare
07dbc21 to
3d97e8c
Compare
3d97e8c to
c85de9d
Compare
| */ | ||
| private getNegotiateChallenge(error: LegacyElasticsearchError) { | ||
| private getNegotiateChallenge(error: errors.ResponseError) { | ||
| // We extract headers from the original Elasticsearch error and not from the top-level `headers` |
There was a problem hiding this comment.
note: well, in fact it's NodeJS that merges these headers, but we can pretend we don't know that 🙂
| body: { x509_certificate_chain: certificateChain }, | ||
| }); | ||
| result = ( | ||
| await this.options.client.asInternalUser.transport.request({ |
There was a problem hiding this comment.
note: hopefully we can publish spec for this API in the future (being discussed in https://github.com/elastic/elasticsearch/issues/67189)
| const { body: response } = await this.options.elasticsearchClient.deleteByQuery( | ||
| { | ||
| index: this.indexName, | ||
| refresh: true, |
There was a problem hiding this comment.
note: wait_for is actually not supported by the deleteByQuery
|
Pinging @elastic/kibana-security (Team:Security) |
|
ACK: reviewing |
legrego
left a comment
There was a problem hiding this comment.
This was a ton of work, nice job! Just a few optional nits and questions, so I won't hold up approval. Thanks for taking care of this 💚
We also have some stray setup of the legacy client in plugin.test.ts that we can cleanup:
kibana/x-pack/plugins/security/server/plugin.test.ts
Lines 46 to 47 in 951aa66
| * @deprecated Use `authc` methods from the `SecurityServiceStart` contract instead. | ||
| */ | ||
| authc: Pick<AuthenticationServiceSetup, 'getCurrentUser'>; | ||
| authc: Pick<AuthenticationServiceStart, 'getCurrentUser'>; |
There was a problem hiding this comment.
It feels strange to export a start service from our setup contract. I can live with this since it's deprecated though
There was a problem hiding this comment.
Yeah, you're right, I'll just duplicate definition here.
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
|
|
||
| export function elasticsearchClientPlugin(Client: any, config: unknown, components: any) { |
| const { body: response } = await this.options.elasticsearchClient.deleteByQuery( | ||
| { | ||
| index: this.indexName, | ||
| refresh: true, |
| @@ -4,50 +4,52 @@ | |||
| * you may not use this file except in compliance with the Elastic License. | |||
| */ | |||
There was a problem hiding this comment.
I really like how we can mock the explicit API calls that we expect to make, without having to mock the generic callAsInternalUser anymore and hope that we're calling it correctly 🏅
| }); | ||
| } = ( | ||
| await this.options.client.security.getToken<{ | ||
| access_token: string; |
There was a problem hiding this comment.
question Do you know if there type improvements we can eventually upstream to the ES client, or is this intentionally generic? I know there are varied responses from ES that we can get here, but there appers to be some common fields that we could potentially leverage.
There was a problem hiding this comment.
AFAIK we'll get much better type definitions soon, see #83808 for more details.
Once this merges I think we can improve missing pieces on case-by-case basis.
|
|
||
| if (!this.authenticator) { | ||
| this.logger.error('Authenticator is not initialized yet.'); | ||
| return response.internalError(); |
There was a problem hiding this comment.
Yep, agree, will change, thanks!
| }); | ||
|
|
||
| const getCurrentUser = (request: KibanaRequest) => { | ||
| if (!this.license.isEnabled()) { |
There was a problem hiding this comment.
question I know you just moved this as-is from setup, but is there a reason we need to perform a license check here?
If the license doesn't enable security, then we'd presumably not have an AuthenticatedUser on the request state, so we'd still end up returning null.
There was a problem hiding this comment.
Good point, let me double check.
| // since `WWW-Authenticate` values can also include commas. | ||
| const challenges = ([] as string[]).concat( | ||
| (error.output.headers as { [key: string]: string })[WWWAuthenticateHeaderName] | ||
| error.body?.error?.header?.[WWWAuthenticateHeaderName] || [] |
There was a problem hiding this comment.
note: I didn't test this as part of my review, but I will if you'd like me to.
There was a problem hiding this comment.
No worries, I specifically checked this. We have integration tests that test this behavior and they failed when I initially tried to use error.headers.
| realm: this.realm, | ||
| }, | ||
| }); | ||
| result = ( |
There was a problem hiding this comment.
nit: for the endpoints where we need to use transport.request, can we add a comment linking to https://github.com/elastic/elasticsearch/issues/67189? That will be really helpful for future me to remember why we did it this way 🙂
There was a problem hiding this comment.
Yep, will do, thanks!
| path: '/_security/oidc/prepare', | ||
| body: params, | ||
| }) | ||
| ).body as any; |
There was a problem hiding this comment.
🤣 Yeah, that's exactly how I feel about it 🙈
💚 Build SucceededMetrics [docs]
History
To update your PR or re-run it, just comment with: |
…lastic#87094) # Conflicts: # x-pack/plugins/security/server/authentication/authentication_service.ts # x-pack/plugins/security/server/authentication/providers/base.mock.ts # x-pack/plugins/security/server/authentication/providers/saml.test.ts # x-pack/plugins/security/server/authentication/providers/saml.ts
|
7.x/7.12.0: 22d85e7 |

The last PR in a series of PRs to migrate Security plugin to a new Elasticsearch client:
ElasticsearchClientPluginas we can now use either Client's default method ortransport.request(for SAML/OIDC/PKI only)Blocked by: #87091