使用 MSI 从 Azure 函数将文件写入 Azure Data Lake 时出错

Posted

技术标签:

【中文标题】使用 MSI 从 Azure 函数将文件写入 Azure Data Lake 时出错【英文标题】:Error writing a file to Azure Data Lake from an Azure function using MSI 【发布时间】:2018-10-04 02:05:27 【问题描述】:

我正在尝试创建一个写入 Azure Data Lake Store 的 Azure 函数。 我正在使用托管服务身份来管理身份验证内容。

我已在函数应用上启用 MSI。我还启用了 Function 应用程序以访问所需的 Data Lake Store。 我正在使用以下代码获取令牌并写入 ADL。 我错过了什么吗?

var azureServiceTokenProvider = new AzureServiceTokenProvider();
string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://datalake.azure.net");
var client = AdlsClient.CreateClient(_adlsAccountName, accessToken);
using (var stream = client.CreateFile(fileName, IfExists.Overwrite))
    
        byte[] textByteArray = Encoding.UTF8.GetBytes("Winter is coming! \r\n");
        stream.Write(textByteArray, 0, textByteArray.Length);
    

我的代码失败并出现以下错误。

with exception Microsoft.Azure.DataLake.Store.AdlsException: Error in creating file /Path/tempFile0.txt.

**Operation: CREATE failed with HttpStatus:Unauthorized Error: Uexpected error in JSON parsing.**

Last encountered exception thrown after 1 tries. [Uexpected error in JSON parsing]

[ServerRequestId:<Some ID>]

at Microsoft.Azure.DataLake.Store.AdlsClient.CreateFile(String filename, IfExists mode, String octalPermission, Boolean createParent)

【问题讨论】:

【参考方案1】:

将“Bearer”添加到访问令牌对我有用。像这样(其他一切都保持不变),

var client = AdlsClient.CreateClient(_adlsAccountName, “Bearer “ + accessToken);

部分感谢 Arturo Lucatero 的 Github 文档,其中提到了这一点。 https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/active-directory/managed-service-identity/tutorial-linux-vm-access-datalake.md

【讨论】:

【参考方案2】:

我主要使用以下 sn-p 从 Azure Functions 进行身份验证和写入 Data Lake:

var clientCredential = new ClientCredential(clientId, clientSecret);
var creds = ApplicationTokenProvider.LoginSilentAsync("domainId", clientCredential).Result;
_client = new DataLakeStoreFileSystemManagementClient(creds);

clientIdclientSecret 分别是:

来自 AD 的 ObjectId 一个秘密

所以基本上你必须创建一个服务主体并从门户获取这些特定属性。

然后我可以使用以下内容:

public async Task AppendToFile(string destinationPath, string content)

    using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(content)))
    
        await _client.FileSystem.ConcurrentAppendAsync("datalakeaccount", destinationPath, stream, appendMode: AppendModeType.Autocreate);
    

将数据写入 ADLS。

您也可以参考this博文。

【讨论】:

谢谢@Kamo,但我想使用 MSI 进行身份验证,这样我就可以避免将客户端 ID 和机密存储在 Key Vault 中。

以上是关于使用 MSI 从 Azure 函数将文件写入 Azure Data Lake 时出错的主要内容,如果未能解决你的问题,请参考以下文章

Azure 函数中的 Az.Functions 模块引发错误

az login 从 github 操作任务失败

从 Azure 函数将消息写入 Azure 服务总线队列

使用Wix将整个目录添加到MSI数据库的规范方法是什么?

从 azure 数据工厂调用 azure 函数端点时出错

使用 Databricks 将文件从 Azure 文件移动到 ADLS Gen 2 并返回