-
Notifications
You must be signed in to change notification settings - Fork 9.1k
HDFS-15765. WebHdfs: add support for basic auth and custom API path #5447
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
base: trunk
Are you sure you want to change the base?
Conversation
💔 -1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
@@ -120,7 +136,7 @@ public HttpURLConnection configure(HttpURLConnection connection) | |||
} | |||
} | |||
|
|||
return conn; | |||
return new BasicAuthConfigurator(conn, basicAuthCredentials); |
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.
should we have something like:
private ConfigurationConfigurator getConfigurator(ConfigurationConfigurator configurator, String basicAuthCred) {
if(basicAuthCred != null && !basicAuthCred.isEmpty()) {
return new BasicAuthConfigurator(configurator, basicAuthCred);}
else {return configurator;}
}
and instead of creating new object of basicAuthConfigurator, we call this new method. And if an object of BasicAuthConfigurator can be made, method will return that new object.
What you say?
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.
Sounds reasonable! I've made the change.
conf.configure(conn); | ||
Mockito.verify(conn, Mockito.times(1)).setRequestProperty( | ||
"AUTHORIZATION", | ||
"Basic dXNlcjpwYXNz" |
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.
should we have "Basic " + Base64.getEncoder().encodeToString( credentials.getBytes(StandardCharsets.UTF_8)
as its not clear from test how user:pass is converting to dXNlcjpwYXNz
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.
I've taken that string from testing a basic auth implementation in cURL, but I can see how it's confusing here. I've applied the suggested change.
Thanks for the review @saxenapranav, I've applied the suggested changes. |
🎊 +1 overall
This message was automatically generated. |
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.
Thank you for taking previous comments. Have added some suggestion.
@Hexiaoqiao, requesting you to kindly review the PR please.
Regards.
@@ -33,6 +33,16 @@ public class BasicAuthConfigurator implements ConnectionConfigurator { | |||
private final ConnectionConfigurator parent; | |||
private final String credentials; | |||
|
|||
static public ConnectionConfigurator getConfigurator( |
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.
Since this method has to be called by URLConnectionFactory which is in same package. Lets have it package-protected and remove public
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.
Should this method be moved to URLConnectionFactory
class only?
Reason being, when external class calls BasicAuthConfigurator.getConfigurator
, to developer it can look that we want something out of BasicAuthConfigurator
, but instead it either gives BasicAuthConfigurator object or parent-configurator object. What you feel?
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.
Good point, we might as well move it to URLConnectionFactory
and make it private there. I've made the change.
HdfsClientConfigKeys.DFS_CLIENT_WEBHDFS_USE_BASE_PATH_KEY, | ||
HdfsClientConfigKeys.DFS_CLIENT_WEBHDFS_USE_BASE_PATH_DEFAULT | ||
); | ||
if (uri.getPath() != null && !uri.getPath().equals("") && useBasePath) { |
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.
although uri can not be null, but better to have null-check on that.
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.
I've added a uri != null
check 👍
…eateBasicAuthConfigurator
Thanks for the additional look @saxenapranav! I've applied the suggested changes. Hey @Hexiaoqiao, Pranev mentioned that you could help with further review. Please let me know if you'd like me to make additional changes! |
💔 -1 overall
This message was automatically generated. |
Description of PR
WebHdfsFileSystem
didn't provide any support for HTTP BASIC authentication (username/password). This patch adds that feature. When specifying filesystem URI, the credentials part (user:pass@
) is now parsed properly and used forAuthorization
header.Additionally, base path specified in filesystem URL used to be ignored. This patch adds configuration option
dfs.client.webhdfs.use-base-path
that, when enabled, indicates that this path should be used as API prefix. This allows specifying/gateway/gatewayname
when using WebHdfs for Apache Knox. When base path contains/webhdfs/v1
, it is ignored, since we always append that.Option
dfs.client.webhdfs.use-base-path
defaults to false because it could introduce a backward compatibility break. Some WebHdfs users could have typos or something random as path, and before this patch it would simply be ignored. By setting the default to false, we make sure that it won't break any existing setup.Note that issue HDFS-15765 is also about Kerberos auth. This patch only addresses the base path and basic authentication portion, I didn't investigate the Kerberos auth since we don't use in our setup.
How was this patch tested?
I tested it with WebHdfs secured by Apache Knox with basic authorization, but without Kerberos. I had a test script that would perform a file upload. I set
dfs.client.webhdfs.use_basepath
to true, and usedswebhdfs://admin:admin-password@localhost:8443/gateway/docker/
as filesystem URI. Without my patch, both theadmin:admin-password
credentials and/gateway/docker
API base path would be ignored. With it, file upload worked.For code changes:
LICENSE
,LICENSE-binary
,NOTICE-binary
files?