-
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
[POC] /app/* requests authenticate against Elasticsearch #17724
Conversation
Whenever the user hits a route that would render a specific application, if we aren't using any auth with HapiJS, execute a pre-flight request against ES, and if we get a 401 then redirect the user to the very baseRoute which will do the 401 with the WWW-Authenticate header and then redirect the user back to the app.
💔 Build Failed |
Perhaps |
@spalger that's interesting... do you know how HEAD requests are auth'ed against ES? It looks like performing a HEAD request similar to the following that don't exist would potentially work, but that seems really weird:
|
HEAD requests should perform just like GET requests except skip over sending the body, so that could work too. |
💔 Build Failed |
💚 Build Succeeded |
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.
Couple notes, but my primary feedback is that I'm not a huge fan of the redirect, the new redirectApp
query string param, or the duplication of logic (wrt. maintenance mostly).
Are we sending users back to /
because the path that we send the first challenge response is really important? What if we had a pre
handler that was shared between these two methods and both /
and /app/*
sent challenge responses?
If nothing else can we unify the logic for fetching the challenge response rather than recreating similar methods in both places?
}); | ||
return null; | ||
} catch (err) { | ||
if (err.statusCode !== 401) { |
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 negative condition confused me at first, I think flipping the branches would make the intention more obvious.
@@ -16,8 +16,29 @@ import { setupXsrf } from './xsrf'; | |||
export default async function (kbnServer, server, config) { | |||
server = kbnServer.server = new Hapi.Server(); | |||
|
|||
const getAuthChallengeResponse = async (req) => { | |||
if (req.auth.strategy || req.auth.mode) { |
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.
Mind adding a comment that explains the intention behind this check?
@kobelb, couldn't you do this with a custom authentication plugin for hapi? You could then make that the default strategy and all routes (including new plugin routes) would have to go through this authentication. |
We're sending the users back to "/" because of the way that Authentication headers are "cached" and provided by the browser. If we were to respond with a 401 and the By redirecting to "/" before we set this header, the Authentication header that is set here will be sent to all paths inside Kibana automatically. @trevan yeah, we could use a HapiJS authentication plugin to do this pre-flight authorization check on every route. Initially, I didn't pursue this approach because of the overhead of doing this pre-flight request on every endpoint when most of them actually handle the 401s appropriately, and I didn't want to incur this additional overhead. It's a solution that is potentially worth pursuing. To be honest, I'm not that big of a fan of this solution that I've proposed, and I'd prefer we either make every route handle the 401s appropriately, or move to a more comprehensive solution, perhaps the one that @trevan mentioned. |
@kobelb, I think one way to reduce the overhead is to check if the request has an authentication header. If a request authentication header is available, then the 401 WWW-Authenticate header should have already been sent back in an earlier response. |
Closing this to revise the approach and I'll throw up another PR. |
To remedy #9583 in a more holistic manner where we don't have to ensure every API endpoint returns the
WWW-Authenticate
header properly, this PR performs a "pre-flight" request against Elasticsearch using the current request to ensure the user is authenticated. If they aren't authenticated, then we redirect them to the application root where we can ensure that endpoint sets the headers properly for all child paths.This conceptually will prevent most APIs from having to handle the WWW-Authenticate headers properly themselves, but there are some scenarios where the user will have to refresh the page to get the auth redirect.