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

Security - remove auth scope provider #36998

Merged
merged 14 commits into from
May 29, 2019

Conversation

legrego
Copy link
Member

@legrego legrego commented May 23, 2019

Summary

The security plugin provides a way for other plugins to append "scopes" to the authenticated user. Based on a conversation here, this is not something we want to migrate to the new platform.

This PR removes the auth scope provider, and replaces its usage within the Dashboard Only Mode plugin with a slightly more straightforward implementation.

return h.continue;
}

const user = auth.credentials;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic copied from dashboard_mode_auth_scope

@legrego legrego added chore release_note:skip Skip the PR/issue when compiling release notes v7.3.0 v8.0.0 labels May 23, 2019
@elasticmachine

This comment has been minimized.

@elasticmachine

This comment has been minimized.

@elasticmachine

This comment has been minimized.

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@legrego
Copy link
Member Author

legrego commented May 24, 2019

retest

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@legrego legrego marked this pull request as ready for review May 24, 2019 22:58
@legrego legrego requested a review from a team as a code owner May 24, 2019 22:58
@legrego legrego added the Team:Security Team focused on: Auth, Users, Roles, Spaces, Audit Logging, and more! label May 24, 2019
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-security

@@ -25,9 +27,27 @@ export function createDashboardModeRequestInterceptor(dashboardViewerApp) {
type: 'onPostAuth',
async method(request, h) {
const { auth, url } = request;
const user = auth.credentials;
Copy link
Member Author

@legrego legrego May 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you can tell from the commit history in this PR, the ordering of operations in this function is rather fragile.

Previously, this logic was part of dashboard_mode_auth_scope, which ran after a successful authentication. Now, this runs as part of "onPostAuth", which runs after auth, but also runs when security is disabled completely.

The existing (and current) logic uses the UI Settings service to retrieve the list of dashboard-only-mode roles. The act of retrieving this setting ends up creating the config document if it doesn't already exist. Various functional tests have come to indirectly rely on this behavior, so I've opted to maintain that in this PR. I had originally hoped to optimize the existing implementation by not querying the UI Settings Service unless strictly necessary, but I wasn't able to do so without also revisiting all of the existing functional tests. I vote to work in that when we remove dashboard-only-mode altogether.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The act of retrieving this setting ends up creating the config document if it doesn't already exist. Various functional tests have come to indirectly rely on this behavior, so I've opted to maintain that in this PR. I had originally hoped to optimize the existing implementation by not querying the UI Settings Service unless strictly necessary, but I wasn't able to do so without also revisiting all of the existing functional tests. I vote to work in that when we remove dashboard-only-mode altogether.

That's a bummer :/ How many (approximately) of such weird tests we have? I'm fine with leaving it as is, just curious.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How many (approximately) of such weird tests we have? I'm fine with leaving it as is, just curious.

It's hard to quantify this since the FTR doesn't run test suites to completion once it finds a test failure. I know we had failures in infra and canvas, but I'm sure there are a number of other impacted suites.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, thanks, that's what I wanted to know. I was just curious whether tests were failing within one "area" or not.

@legrego legrego requested a review from azasypkin May 28, 2019 13:50
@azasypkin
Copy link
Member

ACK: started to review, planning to finish today or tomorrow at the latest.

Copy link
Member

@azasypkin azasypkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just a couple of minor nits. Thanks for doing this, I always wanted to get rid of auth scopes ^feature^ 🙂

@@ -133,11 +132,7 @@ class Authenticator {
* @param authScope AuthScopeService instance.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: please remove authScope from JSDoc as well.

// Complement user returned from the provider with scopes.
scope: await this.authScope.getForRequestAndUser(request, authenticationResult.user!),
} as any);
return AuthenticationResult.succeeded(authenticationResult.user as any);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: authenticationResult.user as any ---> authenticationResult.user! would be more appropriate.

const user = auth.credentials;
const roles = user ? user.roles : [];

if (!user) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: since we create roles even if user isn't defined, can't we just do something like this instead and use our roles list below instead of user.roles?

// Clarifying comment goes here ....
const roles = (auth.credentials && auth.credentials.roles) || [];
if (roles.length === 0) {
  return h.continue;
}

Or the way it's done also related to these weird functional tests that depend on config object? If so, feel free to ignore this suggestion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or the way it's done also related to these weird functional tests that depend on config object? If so, feel free to ignore this suggestion.

Yep, it was done this way because of the weird functional tests

const isSuperUser = user.roles.find(role => role === superuserRole);

const enforceDashboardOnlyMode = isDashboardOnlyModeUser && !isSuperUser;
if (enforceDashboardOnlyMode) {
if (url.path.startsWith('/app/kibana')) {
// If the user is in "Dashboard only mode" they should only be allowed to see
// that app and none others. Here we are intercepting all other routing and ensuring the viewer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uh oh: we have a link to x-pack-kibana repo :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha, good catch, will remove

@@ -7,12 +7,14 @@
import Boom from 'boom';

import {
AUTH_SCOPE_DASHBORD_ONLY_MODE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can you please also get rid of AUTH_SCOPE_DASHBORD_ONLY_MODE in x-pack/plugins/dashboard_mode/common/constants.js?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't believe I missed that! will do!

@@ -108,11 +105,11 @@ describe('DashboardOnlyModeRequestInterceptor', () => {
describe('request has correct auth scope scope', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: test title is outdated

not related: I've noticed we also reference to auth scope from comment in x-pack/plugins/spaces/server/lib/request_inteceptors/on_post_auth_interceptor.ts, probably some left over.

@@ -25,9 +27,27 @@ export function createDashboardModeRequestInterceptor(dashboardViewerApp) {
type: 'onPostAuth',
async method(request, h) {
const { auth, url } = request;
const user = auth.credentials;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The act of retrieving this setting ends up creating the config document if it doesn't already exist. Various functional tests have come to indirectly rely on this behavior, so I've opted to maintain that in this PR. I had originally hoped to optimize the existing implementation by not querying the UI Settings Service unless strictly necessary, but I wasn't able to do so without also revisiting all of the existing functional tests. I vote to work in that when we remove dashboard-only-mode altogether.

That's a bummer :/ How many (approximately) of such weird tests we have? I'm fine with leaving it as is, just curious.

const uiSettings = request.getUiSettingsService();
const dashboardOnlyModeRoles = await uiSettings.get(CONFIG_DASHBOARD_ONLY_MODE_ROLES);

if (!isAppRequest || !dashboardOnlyModeRoles || !roles || roles.length === 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional nit: I'd say the perf impact of find on roles is negligible comparing to async uiSettings.get call, so maybe there is no need to have this additional return path (and assuming we'll do roles check in the if above) and always treat this advanced setting a defined array.

const dashboardOnlyModeRoles = await uiSettings.get(CONFIG_DASHBOARD_ONLY_MODE_ROLES) || [];

nit: also can you please leave a comment in code explaining why we always call uiSettings.get, so that we don't forget that?

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@legrego legrego merged commit 38eb16d into elastic:master May 29, 2019
legrego added a commit to legrego/kibana that referenced this pull request May 29, 2019
* remove auth scope provider

* handle missing roles

* guard for unauthenticated calls

* update functional tests to not expect a scope property

* there's always money in the banana stand

* revert interceptor optimizations

* protect against missing roles

* address pr feedback

* remove scope as expected property on kerberos auth response
@legrego legrego deleted the security/remove-auth-scopes branch May 29, 2019 15:04
legrego added a commit that referenced this pull request May 29, 2019
* remove auth scope provider

* handle missing roles

* guard for unauthenticated calls

* update functional tests to not expect a scope property

* there's always money in the banana stand

* revert interceptor optimizations

* protect against missing roles

* address pr feedback

* remove scope as expected property on kerberos auth response
jkakavas pushed a commit to jkakavas/kibana that referenced this pull request May 30, 2019
* remove auth scope provider

* handle missing roles

* guard for unauthenticated calls

* update functional tests to not expect a scope property

* there's always money in the banana stand

* revert interceptor optimizations

* protect against missing roles

* address pr feedback

* remove scope as expected property on kerberos auth response
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chore release_note:skip Skip the PR/issue when compiling release notes Team:Security Team focused on: Auth, Users, Roles, Spaces, Audit Logging, and more! v7.3.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants