试图在控制台中通过 Hadoop 客户端使用用户名和密码验证类型连接到 Azure Data Lake 存储 Gen2,并收到错误信息。
java.lang.NullPointerException
at org.apache.hadoop.fs.azurebfs.oauth2.AzureADAuthenticator.consumeInputStream(AzureADAuthenticator.java:341)
at org.apache.hadoop.fs.azurebfs.oauth2.AzureADAuthenticator.getTokenSingleCall(AzureADAuthenticator.java:271)
at org.apache.hadoop.fs.azurebfs.oauth2.AzureADAuthenticator.getTokenCall(AzureADAuthenticator.java:212)
at org.apache.hadoop.fs.azurebfs.oauth2.AzureADAuthenticator.getTokenUsingClientCreds(AzureADAuthenticator.java:95)
at org.apache.hadoop.fs.azurebfs.oauth2.UserPasswordTokenProvider.refreshToken(UserPasswordTokenProvider.java:54)
at org.apache.hadoop.fs.azurebfs.oauth2.AccessTokenProvider.getToken(AccessTokenProvider.java:50)
at org.apache.hadoop.fs.azurebfs.services.AbfsClient.getAccessToken(AbfsClient.java:546)
at org.apache.hadoop.fs.azurebfs.services.AbfsRestOperation.executeHttpOperation(AbfsRestOperation.java:150)
at org.apache.hadoop.fs.azurebfs.services.AbfsRestOperation.execute(AbfsRestOperation.java:124)
at org.apache.hadoop.fs.azurebfs.services.AbfsClient.getFilesystemProperties(AbfsClient.java:197)
at org.apache.hadoop.fs.azurebfs.AzureBlobFileSystemStore.getIsNamespaceEnabled(AzureBlobFileSystemStore.java:181)
at org.apache.hadoop.fs.azurebfs.AzureBlobFileSystemStore.getFileStatus(AzureBlobFileSystemStore.java:454)
at org.apache.hadoop.fs.azurebfs.AzureBlobFileSystem.getFileStatus(AzureBlobFileSystem.java:395)
at org.apache.hadoop.fs.Globber.getFileStatus(Globber.java:65)
at org.apache.hadoop.fs.Globber.doGlob(Globber.java:294)
at org.apache.hadoop.fs.Globber.glob(Globber.java:149)
at org.apache.hadoop.fs.FileSystem.globStatus(FileSystem.java:2016)
at org.apache.hadoop.fs.shell.PathData.expandAsGlob(PathData.java:353)
at org.apache.hadoop.fs.shell.Command.expandArgument(Command.java:250)
at org.apache.hadoop.fs.shell.Command.expandArguments(Command.java:233)
at org.apache.hadoop.fs.shell.FsCommand.processRawArguments(FsCommand.java:104)
at org.apache.hadoop.fs.shell.Command.run(Command.java:177)
at org.apache.hadoop.fs.FsShell.run(FsShell.java:327)
at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:76)
at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:90)
at org.apache.hadoop.fs.FsShell.main(FsShell.java:390)
做了什么。
创建存储账户,使用 https:/docs.microsoft.comen-usazurestorageblobsdata-lake-storag-quickstart-creative-account。
使用以下方法创建Azure AD应用程序 https:/docs.microsoft.comen-usazureactive-directorydevelophowto-create-service-principal-portal。
在访问控制(IAM)中,将AD用户添加到存储账户中,成为STORAGE BLOB DATA OWNER。
根据 Apache文档 我创建了一个控制台命令
hadoop fs -Dfs.azure.ssl.channel.mode=Default_JSSE
-Dfs.azure.account.auth.type=OAuth
-Dfs.azure.account.oauth.provider.type=org.apache.hadoop.fs.azurebfs.oauth2.UserPasswordTokenProvider
-Dfs.azure.account.oauth2.client.endpoint=https://login.microsoftonline.com/<TENANT ID>/oauth2/v2.0/authorize
-Dfs.azure.account.oauth2.user.name=<[email protected]>
-Dfs.azure.account.oauth2.user.password=<PASSWORD>
-ls abfss://<CONTAINER NAME>@<STORAGE ACCOUNT>.dfs.core.windows.net/
如果尝试使用这个端点
https://login.microsoftonline.com/<TENANT ID>/oauth2/v2.0/token
输出是
ls: AADToken: HTTP connection failed for getting token from AzureAD. Http response: 400 Bad Request
所以下面的命令应该显示容器中的文件夹和文件列表。是命令有问题还是Azure中的容器配置有问题?请提供建议。
无论您是使用 Azure AD 用户还是服务委托人,您都必须使用 OAuth2 V1 令牌端点,因为它是由 Authenticator 类支持的。这是令牌端点的 URL。
https://login.microsoftonline.com/{TENANT_ID}/oauth2/token
这里 你可以找到V1和V2端点的区别。
也就是说,你必须使用的控制台命令变成了。
hadoop fs -Dfs.azure.ssl.channel.mode=Default_JSSE \
-Dfs.azure.account.auth.type=OAuth \
-Dfs.azure.account.oauth.provider.type=org.apache.hadoop.fs.azurebfs.oauth2.UserPasswordTokenProvider \
-Dfs.azure.account.oauth2.client.endpoint=https://login.microsoftonline.com/{TENANT_ID}/oauth2/token \
-Dfs.azure.account.oauth2.user.name={[email protected]} \
-Dfs.azure.account.oauth2.user.password={PASSWORD} \
-ls abfss://{CONTAINER NAME}@{STORAGE_ACCOUNT}.dfs.core.windows.net/
根据你的问题 似乎你也想用服务委托人进行身份验证 这样的话,你就必须使用... ClientCredsTokenProvider 而不是 UserPasswordTokenProvider 如下图所示。
hadoop fs -Dfs.azure.ssl.channel.mode=Default_JSSE \
-Dfs.azure.account.auth.type=OAuth \
-Dfs.azure.account.oauth.provider.type=org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider \
-Dfs.azure.account.oauth2.client.endpoint=https://login.microsoftonline.com/{TENANT_ID}/oauth2/token \
-Dfs.azure.account.oauth2.client.id={CLIENT_ID} \
-Dfs.azure.account.oauth2.client.secret={SECRET_KEY} \
-ls abfss://{CONTAINER NAME}@{STORAGE_ACCOUNT}.dfs.core.windows.net/
你也可以将auth信息存储在core-site.xml文件中,这一点在 hadoop docs. 在你想使用多个存储账户的情况下,你可以将属性名改为以dfs端点结尾,如下例所示。
<property>
<name>fs.azure.account.auth.type.{STORAGE_ACCOUNT}.dfs.core.windows.net</name>
<value>OAuth</value>
<description>
Use OAuth authentication
</description>
</property>
<property>
<name>fs.azure.account.oauth.provider.type.{STORAGE_ACCOUNT}.dfs.core.windows.net</name>
<value>org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider</value>
<description>
Use client credentials
</description>
</property>
<property
<name>fs.azure.account.oauth2.client.endpoint.{STORAGE_ACCOUNT}.dfs.core.windows.net</name>
<value>https://login.microsoftonline.com/{TENANT_ID}/oauth2/token</value>
<description>
URL of OAuth endpoint
</description>
</property>
<property>
<name>fs.azure.account.oauth2.client.id.{STORAGE_ACCOUNT}.dfs.core.windows.net</name>
<value>{CLIENT_ID}</value>
<description>
Client ID
</description>
</property>
<property>
<name>fs.azure.account.oauth2.client.secret.{STORAGE_ACCOUNT}.dfs.core.windows.net</name>
<value>{SECRET_KEY}</value>
<description>
Secret
</description>
</property>
对不起,如果太晚了,我只是遇到了这个问题 而这个问题是在寻找解决方案的路径, 当我得到它的工作,我想有人可能会发现这个帮助。