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

Identity and access control foundation for OpenSearch #5925

Closed
wants to merge 3 commits into from

Conversation

peternied
Copy link
Member

@peternied peternied commented Jan 18, 2023

Description

Adding a new module and plugin interface that provides identity and access control inside of OpenSearch. This is the founding building block, see more high level thoughts here on our recent blog.

The new extension point, IdentityPlugin, is added with IdentityService handling that plugin interface. IdentitySevice authenticates users and enables access control systems. Adding HTTP basic authentication in the RestController the default NoopIdentityPlugin changes no behavior.

When the identity feature flag is enabled the identity-shiro module is loaded into the IdentityService. This implementations includes an admin user backed through the Apache Shiro system. By partitioning these features through a plugin interface it isolate the dependencies if we ever switch out the underlying library.

Project tracking addition features and functionality

Outstanding Changes

  • Integration testing
  • Unit testing

Issues Resolved

Check List

  • New functionality includes testing.
    • All tests pass
  • New functionality has been documented.
    • New functionality has javadoc added
  • Commits are signed per the DCO using --signoff
  • Commit changes are listed out in CHANGELOG.md file (See: Changelog)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@peternied
Copy link
Member Author

FYI @opensearch-project/security Please take a look, this is a departure in a couple important ways from what we were doing on the feature branch. I'm going to keep iterating on the todo list, please feel free to comment on things in this pull request or for functionality on the todo list as well.

@peternied peternied added the Identity PR/Issues associated with Authentication or Authorization label Jan 18, 2023
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@peternied
Copy link
Member Author

@dbwiddis @saratvemulapalli What do you think of adding a new plugin interface, this would be notable since the identity plugin should not be supported via the extensions interface performance would be a killer?

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@dbwiddis
Copy link
Member

What do you think of adding a new plugin interface ... extensions interface performance would be a killer?

This seems to overly simplify the trade-offs here. We have three locations we can put things: extensions, plugins, or directly in core. I think some/most of the identity functionality should be present in core. What's the use case for putting it in a plugin rather than core?

There might be room for some extensions interacting with identity providers (providing SSO, etc.). Sign-in would generally be a one-time thing where a few milliseconds may not matter as much, while core/plugin would be better for repeated checks during operation.

@cwperks
Copy link
Member

cwperks commented Jan 20, 2023

@peternied looking at this now. This is a bit of a deviation of what is in feature/identity already, can you elaborate on the differences?

@dbwiddis I'll explain the current thinking and state of the feature/identity branch. So far in feature/identity there are core identity features like an internal IdP (a list of users persisted in an OpenSearch system index), basic and bearer auth handling of requests, APIs for interacting with identity inside of plugins and core and soon-to-be REST APIs for interacting with the internal IdP (create/delete User, change password, update User, whoami) and preliminary work on granting permissions.

The way it is organized is in a library (sandbox/lib/opensearch-authn) and a module (sandbox/modules/identity). These are both sandboxed which is where the developer guide advises to put experimental code: https://github.com/opensearch-project/OpenSearch/blob/main/DEVELOPER_GUIDE.md#sandbox. Modules are features that are shipped with OpenSearch by default and are not optional the way that plugins are: https://github.com/opensearch-project/OpenSearch/blob/main/DEVELOPER_GUIDE.md#modules

The library contains the APIs for interacting with security conveniently. This will provide richer APIs for interacting with security than common-utils. This would include methods like Identity.getAuthManager.getSubject() and currentSubject.isPermitted(requestedPermission) which can be used inside of core or plugins to check permissions which currently does not exist.

The identity module is where the internal implementation of security is located and it does use the current plugin extension points of the security plugin to implement REST request authentication via ActionPlugin.getRestHandlerWrapper, register new API actions for interacting with the IdP, register an ActionFilter for authorization, register settings and defining a system index.

This is from the developer guide on modules in OpenSearch:

Features that are shipped with OpenSearch by default but are not built in to the server. We typically separate features from the server because they require permissions that we don't believe all of OpenSearch should have or because they depend on libraries that we don't believe all of OpenSearch should depend on.

We haven't run into any issues building identity as a module, but there's active discussion around leveraging existing extension points vs putting the implementation directly in server.

@peternied
Copy link
Member Author

Basic authentication is working

[2023-01-20T23:43:24,741][INFO ][o.o.r.RestController     ] [runTask-0] Logged in as user ShiroSubject(principal=StringPrincipal(name=admin))

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@peternied
Copy link
Member Author

This is a bit of a deviation of what is in feature/identity already, can you elaborate on the differences?

Yes - we are in heavy-prototyping in the feature branch - which is great. However, following the model established by the extensions team, I want to go directly into what I'd expect to be the final resting place of the identity code and associated module(s). I know this is going to create some complex merge issues in feature/identity, but I've stripped out features that we are not ready to merge into main yet.

Setting aside package naming and file placement, I've created the IdentityPlugin interface to describe the extensibility model, IdentityModule handles picking up the plugin and accessing the functionality throughout the server codebase.

@DarshitChanpura
Copy link
Member

@peternied This PR is a good segue into "identity as core feature". Is that the long term vision for this feature? If so how should the task priorities be considered for future development.

@peternied
Copy link
Member Author

Is that the long term vision for this feature?

Yes! This is a refinement of the work done in features/identity [^1] to a digestible chunk of functionality. I'm borrowing heavily from the work recently done by @ryanbogan to integrate extensions which have a similar trajectory.

If so how should the task priorities be considered for future development.

This is a good topic for the meta issue [^2] around this work, but I would say the project board's readme captures the current status the best [^3]

@peternied
Copy link
Member Author

@dbwiddis This seems to overly simplify the trade-offs here. We have three locations we can put things: extensions, plugins, or directly in core. I think some/most of the identity functionality should be present in core. What's the use case for putting it in a plugin rather than core?

Security evolved outside of core for many years - there are many external implementations of identity and access controls built as plugins. While we own the Security plugin in this project, there are others customers that want to keep using alternative implementations.

By having the a plugin layer it will protect us from ourselves from too much coupling as we iterate. I recently pushed an implementation of this interface I'd be curious what you think of the module and its separation of responsibility.

public ShiroIdentityPlugin(final Settings settings) {
this.settings = settings;

SecurityManager securityManager = new DefaultSecurityManager(InternalRealm.INSTANCE);
Copy link
Member

Choose a reason for hiding this comment

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

The DefaultSecurityManager will create sessions by default. This will not be stateless as basic auth should be.

Copy link
Contributor

@stephen-crawford stephen-crawford left a comment

Choose a reason for hiding this comment

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

I left some comments places with general notes and a couple of things to check.

String username = ((UsernamePasswordToken) token).getUsername();
// Look up the user by the provide username
User userRecord = getInternalUser(username);
// Check for other things, like a locked account, expired password, etc.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this supposed to be a TODO or is that part of the getInternalUser call?

throw new IncorrectCredentialsException();
}
}
// Don't know what to do with this token
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we be including this into main? It seems like this section is still a work in progress.

}

// TODO: Fix this test
// public void testShouldExtractBasicAuthTokenSuccessfully_twoSemiColonPassword() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be removed?

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 need to fix these tests before I can merge, they should be uncommented before then. The TODO above captures

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

Copy link
Contributor

@RyanL1997 RyanL1997 left a comment

Choose a reason for hiding this comment

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

Do we have the lint check for this PR? As Stephen mentioned above, it seems like we are missing some of the additional line space at end of couple files.

@peternied
Copy link
Member Author

Do we have the lint check for this PR? As Stephen mentioned above, it seems like we are missing some of the additional line space at end of couple files.

This pull request is in draft and fixing all CR checks will be required to merge. I'll get around to these, but the functionality is where I am concentrating my efforts.

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@peternied peternied force-pushed the core-identity branch 2 times, most recently from b2162a7 to 403cdec Compare January 27, 2023 04:40
@peternied peternied marked this pull request as ready for review January 27, 2023 04:40
@github-actions
Copy link
Contributor

github-actions bot commented Feb 3, 2023

Gradle Check (Jenkins) Run Completed with:

@peternied
Copy link
Member Author

@reta @nknize @saratvemulapalli I haven't seen any comments - I'm going to flush out the all test and get gradle check passing without waiting on any more feedback.


apply plugin: 'opensearch.internal-cluster-test'

opensearchplugin {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this module will be an ideal candidate for sandbox ?

Copy link
Member Author

Choose a reason for hiding this comment

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

There are a couple of ways to introduce non-GA features into OpenSearch, sandbox changes the build output which is easy to test locally, but difficult from the distribution channels. Using feature flags was recently introduced and is easier to control outside this repository. What do you think of this tradeoff to include the module but have it disabled via feature flag?

public static final String IDENTITY = "opensearch.experimental.feature.identity.enabled";

Copy link
Collaborator

@reta reta Feb 14, 2023

Choose a reason for hiding this comment

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

I believe there are 2 parts to it:

  • the core support (new plugin interfaces), this could be good candidate for feature flags
  • the new experimental plugin (like this one), this could go to sandbox

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'll move the module into sandbox

Copy link
Member

Choose a reason for hiding this comment

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

sandbox changes the build output which is easy to test locally, but difficult from the distribution channels

@peternied Feel free to weigh in on #3677

* @opensearch.experimental
*/
// TODO not sure why ThreadLeakScope.NONE is required
@ThreadLeakScope(ThreadLeakScope.Scope.NONE)
Copy link
Collaborator

Choose a reason for hiding this comment

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

We probably could remove the @ThreadLeakScope(ThreadLeakScope.Scope.NONE), the thread leaks have to be detected

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

}

public InternalRealm build() {
// TODO: Replace hardcoded admin user / user map with an external provider
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍 totally agree, we should not hardcode

@reta
Copy link
Collaborator

reta commented Feb 14, 2023

@reta @nknize @saratvemulapalli I haven't seen any comments - I'm going to flush out the all test and get gradle check passing without waiting on any more feedback.

My apologies @peternied , didn't have time today, did a quick pass but will take a closer look tomorrow, thank you

CHANGELOG.md Outdated

### Dependencies
- Bumps `wiremock-jre8-standalone` from 2.33.2 to 2.35.0
Copy link
Collaborator

Choose a reason for hiding this comment

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

These changes are not related, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Bad merge, cleaning up...

* @return the shiro auth token to be for login
*/
public AuthenticationToken translateAuthToken(org.opensearch.identity.tokens.AuthToken authenticationToken) {
final AuthenticationToken authToken = null;
Copy link
Collaborator

Choose a reason for hiding this comment

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

The authToken is not used here

Copy link
Member Author

Choose a reason for hiding this comment

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

Good call, cleaning this up.


// By default shiro stores session information into a cache, there were performance
// issues with this sessions cache and so are defaulting to a stateless configuration
this.subjectDAO = new StatelessDAO();
Copy link
Collaborator

@reta reta Feb 14, 2023

Choose a reason for hiding this comment

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

I don't think you need StatelessDAO class, you could just disable session storage (and consequently, the cache if needed):

        final DefaultSessionStorageEvaluator evaluator = new DefaultSessionStorageEvaluator();
        evaluator.setSessionStorageEnabled(false);

        final DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        subjectDAO.setSessionStorageEvaluator(evaluator);
        setSubjectDAO(subjectDAO);

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the example, using this.


public ShiroSubject(final AuthTokenHandler authTokenHandler, final org.apache.shiro.subject.Subject subject) {
this.authTokenHandler = authTokenHandler;
this.shiroSubject = subject;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could either authTokenHandler or subject be null?

Copy link
Member Author

Choose a reason for hiding this comment

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

They shouldn't be, adding Objects.requireNonNull(...) to ensure this

@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
final UsernamePasswordToken userToken = (UsernamePasswordToken) token;
final String password = new String(userToken.getPassword());
Copy link
Collaborator

@reta reta Feb 14, 2023

Choose a reason for hiding this comment

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

The password is not needed, you convert from char[] to String and back to char[], just use userToken.getPassword() directly

Copy link
Member

Choose a reason for hiding this comment

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

+1

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

realmName
);

// TODO: Doesn't appear to check the password
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this comment still valid?

Copy link
Member Author

Choose a reason for hiding this comment

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

Nope, removing

}

// If the token was not handled, it was unsupported
throw new UnsupportedTokenException("Unable to support authentication token " + token.getClass().getName());
Copy link
Collaborator

Choose a reason for hiding this comment

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

token could be null here, better to check

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed

* Base test case for integration tests against the identity plugin.
*/
@ThreadLeakScope(ThreadLeakScope.Scope.NONE)
public abstract class AbstractIdentityTestCase extends OpenSearchIntegTestCase {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where this test case is used?

/**
* Represents a principal which has not been authenticated
*/
UNAUTHENTICATED(new StringPrincipal("Unauthenticated"));
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems to be very limited set of possible principals, I think we should not model it as an enumeration but constants:

public final class BuiltinPrincipals {
    public static final Principal UNAUTHENTICATED = new StringPrincipal("Unauthenticated");
}

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 think enums are much more expressive and flexible. I'd like to leave it in, we can clean it up if its cumbersome with further implementation.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Enums imply closed set of choices - this is not the case here

*
* @opensearch.experimental
*/
public class StringPrincipal implements Principal {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we rename it to UsernamePrincipal instead? StringPrincipal is definitely not giving the context what this principal is about.

Copy link
Member Author

Choose a reason for hiding this comment

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

To me user implies human, I think we will be using this object to represent segments of the OpenSearch runtime. I believe we will replace many of the ThreadPool.Names with these principals to limit the kinds of access those thread have.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok, what about NamedPrincipal?

return new BasicAuthToken(authHeaderValueStr);
} else {
if (logger.isDebugEnabled()) {
String tokenTypeTruncated = Strings.substring(authHeaderValueStr, 0, 5);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we should remove the tokenTypeTruncated, it would output weird token types (for example, imagine Digest ... here)

Copy link
Member Author

Choose a reason for hiding this comment

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

In a debugging scenario, I think seeing those weird token times would be useful if you were expecting the request to authenticated and wasn't sure why. What do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I mean, in debugging you could always say that the auth header was not Basic (if you ever need to do that).

/**
* Get the current subject
* */
public Subject getSubject();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could getSubject() return null vaues? If yes, we have to reconsider the API and return Optional<Subject> instead

Copy link
Member Author

Choose a reason for hiding this comment

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

Subject should never be null.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@NotNull on return type?

@saratvemulapalli
Copy link
Member

@reta @nknize @saratvemulapalli I haven't seen any comments - I'm going to flush out the all test and get gradle check passing without waiting on any more feedback.

Sorry for not getting back on this, I am resurfacing from hibernation :).
Looking now..

Copy link
Member

@saratvemulapalli saratvemulapalli left a comment

Choose a reason for hiding this comment

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

Lot of barebones and learning to understand Shiro.
These 2 resources helped me learn:

Couple of questions and dropped few comments:

  • What are your thoughts on re-using existing security plugins authn/authz mechanisms.
    Can we write realms to use all of our business logic we have already built
  • I dont see compliance built into the framework, how do you plan to handle it (atleast to start with audit logging).

CHANGELOG.md Outdated
@@ -9,8 +9,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Add getter for path field in NestedQueryBuilder ([#4636](https://github.com/opensearch-project/OpenSearch/pull/4636))
- Allow mmap to use new JDK-19 preview APIs in Apache Lucene 9.4+ ([#5151](https://github.com/opensearch-project/OpenSearch/pull/5151))
- Add support for ppc64le architecture ([#5459](https://github.com/opensearch-project/OpenSearch/pull/5459))
- Add support to disallow search request with preference parameter with strict weighted shard routing([#5874](https://github.com/opensearch-project/OpenSearch/pull/5874))
- Add identity and access control extension point ([5925](https://github.com/opensearch-project/OpenSearch/pull/5925))
Copy link
Member

Choose a reason for hiding this comment

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

This is assuming changes will not be available in OpenSearch 2.x.
Is that the intention?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for noticing, I've moved this into the Unreleased 2.x section.

This document is confusing to work with for the first time.

*
* @opensearch.experimental
*/
class AuthTokenHandler {
Copy link
Member

Choose a reason for hiding this comment

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

No opinions, trying to understand: Looks like a utility class. This class doesn't have any state, probably can we go static?
Are there more implementations which will end up here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Non static so this class can be dependency injected easily.

private static final Logger logger = LogManager.getLogger(AuthTokenHandler.class);

/**
* Translates shiro auth token from the given header token
Copy link
Member

Choose a reason for hiding this comment

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

super nit:

Suggested change
* Translates shiro auth token from the given header token
* Translates into shiro auth token from the given header token

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks!

private final org.apache.shiro.subject.Subject shiroSubject;

public ShiroSubject(final AuthTokenHandler authTokenHandler, final org.apache.shiro.subject.Subject subject) {
this.authTokenHandler = authTokenHandler;
Copy link
Member

Choose a reason for hiding this comment

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

Isn't authTokenHandler for all subjects the same for OpenSearch?
Does it have to be a member for each subject?

Copy link
Member Author

Choose a reason for hiding this comment

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

Passing via constructor for dependency injection / testing - is there a convention to follow for classes that aren't guice injected but use DI?

@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
final UsernamePasswordToken userToken = (UsernamePasswordToken) token;
final String password = new String(userToken.getPassword());
Copy link
Member

Choose a reason for hiding this comment

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

+1

adminUser.setUsername(new StringPrincipal("admin"));
adminUser.setBcryptHash("$2a$12$VcCDgh2NDk07JGN0rjGbM.Ad41qVR/YFJcgHp0UGns5JDymv..TOG"); // Password 'admin'
final Map<String, User> internalUsers = Map.of("admin", adminUser);
return new InternalRealm(name, internalUsers);
Copy link
Member

Choose a reason for hiding this comment

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

How do we plan to integrate this with existing security plugin users:

  • For new clusters, read through the yml configs and populate them.
  • For existing clusters which already has loaded yml configs, load it from security system index.

Copy link
Member Author

Choose a reason for hiding this comment

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

We've got tasks for building up the UserService and management APIs - when we work on #5883 all these pieces will be included.

final SimpleAuthenticationInfo sai = new SimpleAuthenticationInfo(
userRecord.getUsername(),
userRecord.getBcryptHash(),
realmName
Copy link
Member

Choose a reason for hiding this comment

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

Do you plan to have multiple realms for OpenSearch (one for authn and one for authz)?

Copy link
Member Author

Choose a reason for hiding this comment

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

No plans for multiple realms.

Comment on lines +49 to +52
public Subject getSubject() {
return identityPlugin.getSubject();
}
}
Copy link
Member

Choose a reason for hiding this comment

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

This is clean!!!

Comment on lines 525 to 527
if (!FeatureFlags.isEnabled(FeatureFlags.IDENTITY)) {
return true;
}
Copy link
Member

Choose a reason for hiding this comment

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

I would prefer moving this to L406, lets not get to handleAuthenticateUser if the feature is not enabled.

Copy link
Member Author

Choose a reason for hiding this comment

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

Moved

return false;
}

return true;
Copy link
Member

Choose a reason for hiding this comment

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

By default we should always false and return true only when the subject is authenticated (at L537)

Copy link
Member Author

Choose a reason for hiding this comment

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

Authentication didn't fail so this is accurate, see the other commment thread in this file https://github.com/opensearch-project/OpenSearch/pull/5925/files#r1089137958. Adding a comment in the code that clarifies.

Signed-off-by: Peter Nied <[email protected]>
Signed-off-by: Peter Nied <[email protected]>
Copy link
Member Author

@peternied peternied left a comment

Choose a reason for hiding this comment

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

I'll do the migration to sandbox and the test fixes fast following this most recent push

CHANGELOG.md Outdated
@@ -9,8 +9,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Add getter for path field in NestedQueryBuilder ([#4636](https://github.com/opensearch-project/OpenSearch/pull/4636))
- Allow mmap to use new JDK-19 preview APIs in Apache Lucene 9.4+ ([#5151](https://github.com/opensearch-project/OpenSearch/pull/5151))
- Add support for ppc64le architecture ([#5459](https://github.com/opensearch-project/OpenSearch/pull/5459))
- Add support to disallow search request with preference parameter with strict weighted shard routing([#5874](https://github.com/opensearch-project/OpenSearch/pull/5874))
- Add identity and access control extension point ([5925](https://github.com/opensearch-project/OpenSearch/pull/5925))
Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for noticing, I've moved this into the Unreleased 2.x section.

This document is confusing to work with for the first time.

CHANGELOG.md Outdated

### Dependencies
- Bumps `wiremock-jre8-standalone` from 2.33.2 to 2.35.0
Copy link
Member Author

Choose a reason for hiding this comment

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

Bad merge, cleaning up...

* @opensearch.experimental
*/
// TODO not sure why ThreadLeakScope.NONE is required
@ThreadLeakScope(ThreadLeakScope.Scope.NONE)
Copy link
Member Author

Choose a reason for hiding this comment

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

Done

*
* @opensearch.experimental
*/
class AuthTokenHandler {
Copy link
Member Author

Choose a reason for hiding this comment

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

Non static so this class can be dependency injected easily.

private static final Logger logger = LogManager.getLogger(AuthTokenHandler.class);

/**
* Translates shiro auth token from the given header token
Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks!

/**
* Get the current subject
* */
public Subject getSubject();
Copy link
Member Author

Choose a reason for hiding this comment

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

Subject should never be null.

Comment on lines 525 to 527
if (!FeatureFlags.isEnabled(FeatureFlags.IDENTITY)) {
return true;
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved


try {
final AuthToken token = RestTokenExtractor.extractToken(request);
// If no token was found, continue executing the request
Copy link
Member Author

Choose a reason for hiding this comment

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

This method is authenticate - not authorize. Consider anonymous scenarios, maybe calls like cluster health would be allowed for anonymous requests. These authorizing calls would happen at lower layer where details about the resource associated with the request is against can factor in 403 or allow.

Note; authorization is not included in this change.


try {
final AuthToken token = RestTokenExtractor.extractToken(request);
// If no token was found, continue executing the request
Copy link
Member Author

Choose a reason for hiding this comment

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

Adding this as a comment in the code

return false;
}

return true;
Copy link
Member Author

Choose a reason for hiding this comment

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

Authentication didn't fail so this is accurate, see the other commment thread in this file https://github.com/opensearch-project/OpenSearch/pull/5925/files#r1089137958. Adding a comment in the code that clarifies.

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@peternied
Copy link
Member Author

This change was merged as part of the following pull request

@peternied peternied closed this May 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Identity PR/Issues associated with Authentication or Authorization
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Initial Identity in OpenSearch
10 participants