-
Notifications
You must be signed in to change notification settings - Fork 3.4k
HBASE-26667 Integrate user-experience for hbase-client #4064
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
Conversation
|
🎊 +1 overall
This message was automatically generated. |
|
🎊 +1 overall
This message was automatically generated. |
|
🎊 +1 overall
This message was automatically generated. |
joshelser
left a comment
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.
A couple of nit-picky things, but looks good!
hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionFactory.java
Outdated
Show resolved
Hide resolved
hbase-common/src/main/java/org/apache/hadoop/hbase/security/oauthbearer/OAuthBearerUtils.java
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| /** | ||
| * Check whether an OAuth Beaerer token is provided in environment variable HADOOP_JWT. |
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.
| * Check whether an OAuth Beaerer token is provided in environment variable HADOOP_JWT. | |
| * Check whether an OAuth Bearer token is provided in environment variable HBASE_JWT. |
| ZonedDateTime lifetime = ZonedDateTime.parse(tokens[1]); | ||
| lifetimeMs = lifetime.toInstant().toEpochMilli(); | ||
| } catch (DateTimeParseException e) { | ||
| LOG.warn("Unable to parse JWT expiry: {}", tokens[1]); |
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.
Reading addTokenForUser(String, Token, long), it seems like we don't need to have a lifetime, which matches the warning (not failure) here. Lazy question: do we have an "expectation" on how it should work? Like, does Knox always give us a lifetime? What about the nimbus test server?
If the jwt server doesn't give us a lifetime, do we have any kind of loss of functionality on the HBase client side?
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.
Lifetime is generally needed for the overlap of token renewal when you're having 2 tokens at the same time in your subject credentials. In this case the client have to choose the most recent one for the authentication. This logic is already implemented, but lifetimeMs is a must for this to work.
Yes, in the Knox response you'll get the base64 encoded token and the lifetimeMs in the JSON. Theoretically it's also possible to parse the expiry field from the JWT itself, but the question here is do you want to do that without signature validation? If not, the client will also have to be capable of JWT validation like the server.
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.
Theoretically it's also possible to parse the expiry field from the JWT itself, but the question here is do you want to do that without signature validation? If not, the client will also have to be capable of JWT validation like the server.
Yeah, I would not suggest that we push the validation logic into the client (at least without a very good reason)
but lifetimeMs is a must for this to work.
If lifetimeMs is going to be important for the token selection to work, I think we should just throw an Exception if we can't parse the timestamp. Otherwise, we'll get questions later about why renewal/expiration/selection logic didn't work correctly.
If we're going to focus on Knox as the authorization server, let's build the implementation as to how Knox works. As we want to support other authz servers, it will be easier to codify "supported features" of different authorization servers.
| @Test | ||
| public void testAddTokenFromEnvVar() { | ||
| // Arrange | ||
| User user = User.createUserForTesting(new HBaseConfiguration(), "testuser", new String[] {}); |
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.
| User user = User.createUserForTesting(new HBaseConfiguration(), "testuser", new String[] {}); | |
| User user = User.createUserForTesting(HBaseConfiguration.create(), "testuser", new String[] {}); |
| long numberOfTokens = user.getTokens().stream() | ||
| .filter((t) -> new Text(TOKEN_KIND).equals(t.getKind())) | ||
| .count(); | ||
| assertEquals("Invalid number of tokens on User",1, numberOfTokens); |
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.
| assertEquals("Invalid number of tokens on User",1, numberOfTokens); | |
| assertEquals("Invalid number of tokens on User", 1, numberOfTokens); |
hbase-client/src/main/java/org/apache/hadoop/hbase/security/token/OAuthBearerTokenUtil.java
Show resolved
Hide resolved
2176bd7 to
c11f377
Compare
|
🎊 +1 overall
This message was automatically generated. |
|
🎊 +1 overall
This message was automatically generated. |
|
🎊 +1 overall
This message was automatically generated. |
|
@joshelser The builds are finally green on this patch and I addressed your review comments. PTAL. |
joshelser
left a comment
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.
Unless you think strongly otherwise, let's just throw an exception for missing lifetime or expiration instead of logging a debug message. Otherwise, looks good.
| ZonedDateTime lifetime = ZonedDateTime.parse(tokens[1]); | ||
| lifetimeMs = lifetime.toInstant().toEpochMilli(); | ||
| } catch (DateTimeParseException e) { | ||
| LOG.warn("Unable to parse JWT expiry: {}", tokens[1]); |
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.
Theoretically it's also possible to parse the expiry field from the JWT itself, but the question here is do you want to do that without signature validation? If not, the client will also have to be capable of JWT validation like the server.
Yeah, I would not suggest that we push the validation logic into the client (at least without a very good reason)
but lifetimeMs is a must for this to work.
If lifetimeMs is going to be important for the token selection to work, I think we should just throw an Exception if we can't parse the timestamp. Otherwise, we'll get questions later about why renewal/expiration/selection logic didn't work correctly.
If we're going to focus on Knox as the authorization server, let's build the implementation as to how Knox works. As we want to support other authz servers, it will be easier to codify "supported features" of different authorization servers.
|
🎊 +1 overall
This message was automatically generated. |
|
🎊 +1 overall
This message was automatically generated. |
|
🎊 +1 overall
This message was automatically generated. |
Signed-off-by: Josh Elser <[email protected]>
Implemented the environment variable based approach for detecting available JWT tokens.
ConnectionFactorywill check for the presence of "HADOOP_JWT" environment variable and adds it to user's credentials. Format of value is<base64_encoded_jwt>,<expiry in DateTimeFormatter.ISO_ZONED_DATE_TIME format>Expiry info is optional.