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

Druid authentication/authorization on router's side #73

Open
wants to merge 7 commits into
base: 0.12.1-mmx
Choose a base branch
from

Conversation

esevastyanov
Copy link

Updated the druid-basic-security module to make it work on any Druid component as a user/role manager:

  1. Added dependency on MetadataStorage because it is used as a storage for users/roles entities
  2. Authenticator/authorizer cache/handler/notifier take the class composition from a config

…nent

as user/role manager:
1. Added dependency on MetadataStorage because it is used as a storage
for users/roles
2. Authenticator/authorizer cache/handler/notifier take class composition
form a config
@esevastyanov esevastyanov marked this pull request as ready for review May 23, 2019 12:16
@esevastyanov
Copy link
Author

@egor-ryashin @leventov could you please run integration test locally using 0.12.1-mmx branch?
I tried several times but two integration tests continuously fail on before stage: ITTwitterQueryTest and ITWikipediaQueryTest. Travis checks also failed at the same places.

[ERROR] Failures:
[ERROR]   ITTwitterQueryTest.before:47 » ISE Max number of retries[10] exceeded for Task...
[ERROR]   ITWikipediaQueryTest.before:47 » ISE Max number of retries[10] exceeded for Ta...

@esevastyanov
Copy link
Author

I got the same result for the branch 0.12.1 of incubator-druid

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class BasicAuthClassCompositionConfig

Choose a reason for hiding this comment

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

This class has a lot of fields, but seems that only one of them is used, why is that?

Copy link
Author

Choose a reason for hiding this comment

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

Actually, all of them are in use (see BasicSecurityDruidModule)

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class BasicAuthClassCompositionConfig

Choose a reason for hiding this comment

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

Please add a class-level comment describing something or pointing somewhere.

Copy link
Author

Choose a reason for hiding this comment

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

added

{
if (config.getAuthenticatorMetadataStorageUpdater() != null) {

Choose a reason for hiding this comment

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

This block of code can be extracted as a method.

Choose a reason for hiding this comment

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

Please add some explanation. What is going on here?

Copy link
Author

Choose a reason for hiding this comment

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

Refactored and added description


package io.druid.security.basic.authentication.db.cache;

public class NoopBasicAuthenticatorCacheNotifier implements BasicAuthenticatorCacheNotifier

Choose a reason for hiding this comment

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

Why this class is needed? It's not used in this PR.

Copy link
Author

Choose a reason for hiding this comment

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

It is needed on a config level
https://github.com/metamx/druid-config/pull/99

Choose a reason for hiding this comment

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

Would be nice to specify whether "noop" means "no auth" or "always rejecting auth".


package io.druid.security.basic.authorization.db.cache;

public class NoopBasicAuthorizerCacheNotifier implements BasicAuthorizerCacheNotifier

Choose a reason for hiding this comment

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

Same

Copy link
Author

Choose a reason for hiding this comment

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

I also removed the same classes from test scope so this class is used in tests now

Choose a reason for hiding this comment

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

Same

@leventov
Copy link

There are errors in Travis log: io.druid.server.AsyncQueryForwardingServlet - Can not find Authenticator with Name [allowAll]

@esevastyanov
Copy link
Author

Also updated AWS S3 access and secret keys as they were changed last year so that's why integration tests were failing @leventov

@@ -22,6 +22,14 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
* Basic authentication storage/cache/resource hadler config.

Choose a reason for hiding this comment

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

Typo, handler

@@ -22,6 +22,14 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
* Basic authentication storage/cache/resource hadler config.
* The config is an option to specify classes of user/role managers, caches and notifiers.

Choose a reason for hiding this comment

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

I would put it "BasicAuthClassCompositionConfig provides options to specify authenticator classes..."

/**
* Basic authentication storage/cache/resource hadler config.
* The config is an option to specify classes of user/role managers, caches and notifiers.
* If a config field is specified then the corresponding class is instantiated

Choose a reason for hiding this comment

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

Not very clear, I would put it "If a field in this class is non-null then ..."

public static <T> T getInstance(
Injector injector,
String configClassName,
Class<? extends T> isCoordClass,

Choose a reason for hiding this comment

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

Maybe call the param classRunByCoordinator


package io.druid.security.basic.authentication.db.cache;

public class NoopBasicAuthenticatorCacheNotifier implements BasicAuthenticatorCacheNotifier

Choose a reason for hiding this comment

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

Would be nice to specify whether "noop" means "no auth" or "always rejecting auth".


package io.druid.security.basic.authorization.db.cache;

public class NoopBasicAuthorizerCacheNotifier implements BasicAuthorizerCacheNotifier

Choose a reason for hiding this comment

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

Same

@@ -24,8 +24,8 @@

/**
* Basic authentication storage/cache/resource handler config.
* The config is an option to specify classes of user/role managers, caches and notifiers.
* If a config field is specified then the corresponding class is instantiated
* BasicAuthClassCompositionConfig provides options to specify authenticator/authorizer classes.

Choose a reason for hiding this comment

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

I intended that "of user/role managers, caches and notifiers" is retained - please fix the upstream PR.

@@ -17,8 +17,8 @@ command=java
-Ddruid.indexer.fork.property.druid.processing.buffer.sizeBytes=75000000
-Ddruid.indexer.fork.property.druid.processing.numThreads=1
-Ddruid.indexer.fork.server.http.numThreads=100
-Ddruid.s3.accessKey=AKIAIMKECRUYKDQGR6YQ
-Ddruid.s3.secretKey=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
-Ddruid.s3.accessKey=AKIAJI7DG7CDECGBQ6NA

Choose a reason for hiding this comment

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

Just wonder what s3 storage is accessed by those credentials, is it safe to keep those credentials in github repo?

Copy link
Author

Choose a reason for hiding this comment

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

Choose a reason for hiding this comment

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

I don't understand why we change them?

Copy link
Author

Choose a reason for hiding this comment

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

Since we depend on third-party's s3 account in integration-tests (and it was updated). As a solution, we might duplicate that data into our s3.

return getInstance(
injector,
config.getAuthorizerResourceHandler(),
CoordinatorBasicAuthorizerResourceHandler.class,

Choose a reason for hiding this comment

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

I think we should rename CoordinatorBasicAuthorizerResourceHandler to something else, as it is not bound to Coordinator now.

Copy link
Author

Choose a reason for hiding this comment

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

Let me update names and some logic around centralized user management in the next PR

Choose a reason for hiding this comment

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

Could you create a ticket for that?

Choose a reason for hiding this comment

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

BTW, I wonder what's the purpose of doing it in a separate PR?

Copy link
Author

Choose a reason for hiding this comment

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

As we decided that this feature might be helpful for the community the PR into upstream druid was created and merged. So it would be great to follow this strategy and pull new changes into the upstream before pulling into our fork.

Copy link
Author

Choose a reason for hiding this comment

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

Should I create a ticket in the upstream?

Copy link
Author

Choose a reason for hiding this comment

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

Original PR into Druid
apache#7789

Choose a reason for hiding this comment

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

Should I create a ticket in the upstream?

Yes.

if (configClassName != null) {
// ClassCastException is thrown in case of a mismatch, configuration fix is required.
@SuppressWarnings("unchecked")
final T instance = (T) injector.getInstance(Class.forName(configClassName));

Choose a reason for hiding this comment

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

I think we exposing too much internals in configs propagating the class names for each sub-component. In fact, we would like a switch like ...authorization.management.enabled=true/false which can effectively select required classes for us.

Copy link
Author

Choose a reason for hiding this comment

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

This will require refactoring current DI of the module

Choose a reason for hiding this comment

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

That works for testing, but it's awkward for production.

Copy link
Author

Choose a reason for hiding this comment

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

Agree, this might be improved

Choose a reason for hiding this comment

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

Let's add it to the issue we create for #73 (comment)

@esevastyanov
Copy link
Author

@egor-ryashin I moved everything from merged incubator-druid PR
apache#7789
At first, I intended to do cherry-pick but unfortunately, this anyway requires some code changes as the master branch has different license and package names.
If you have some thoughts on how to make this logic better then let's discuss them separately (in slack channel #d-druid-auth) and implement them in the next PR. It would be great to merge this PR and start a new one with improvements.

@@ -17,8 +17,8 @@ command=java
-Ddruid.indexer.fork.property.druid.processing.buffer.sizeBytes=75000000
-Ddruid.indexer.fork.property.druid.processing.numThreads=1
-Ddruid.indexer.fork.server.http.numThreads=100
-Ddruid.s3.accessKey=AKIAIMKECRUYKDQGR6YQ
-Ddruid.s3.secretKey=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
-Ddruid.s3.accessKey=AKIAJI7DG7CDECGBQ6NA

Choose a reason for hiding this comment

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

I don't understand why we change them?

if (configClassName != null) {
// ClassCastException is thrown in case of a mismatch, configuration fix is required.
@SuppressWarnings("unchecked")
final T instance = (T) injector.getInstance(Class.forName(configClassName));

Choose a reason for hiding this comment

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

That works for testing, but it's awkward for production.

return getInstance(
injector,
config.getAuthorizerResourceHandler(),
CoordinatorBasicAuthorizerResourceHandler.class,

Choose a reason for hiding this comment

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

Could you create a ticket for that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants