如何在Databricks中跨Azure目录操作文件(访问密钥无效)
跨Azure目录在Databricks中访问并复制存储文件的替代方案
针对跨Azure AD目录(租户)访问存储账户时存储密钥认证失败的问题,以下是几种可行的替代认证及文件复制方案:
1. 服务主体(Service Principal)认证
在目标Azure租户中注册一个服务主体,为其分配目标存储账户的**Blob数据参与者(Storage Blob Data Contributor)**权限,然后在Databricks中通过该服务主体完成认证:
配置代码
# 替换为你的服务主体信息和存储账户详情 spark.conf.set("fs.azure.account.auth.type.<storageAccountName>.dfs.core.windows.net", "OAuth") spark.conf.set("fs.azure.account.oauth.provider.type.<storageAccountName>.dfs.core.windows.net", "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider") spark.conf.set("fs.azure.account.oauth2.client.id.<storageAccountName>.dfs.core.windows.net", "<servicePrincipalClientId>") spark.conf.set("fs.azure.account.oauth2.client.secret.<storageAccountName>.dfs.core.windows.net", "<servicePrincipalClientSecret>") spark.conf.set("fs.azure.account.oauth2.client.endpoint.<storageAccountName>.dfs.core.windows.net", "https://login.microsoftonline.com/<targetTenantId>/oauth2/token") # 验证读取 df = spark.read.csv("abfss://<containerName>@<storageAccountName>.dfs.core.windows.net/folder/") display(df) # 跨目录复制文件(示例:从目标存储复制到当前工作区关联的存储) dbutils.fs.cp("abfss://<containerName>@<storageAccountName>.dfs.core.windows.net/source-folder/", "abfss://<localContainer>@<localStorageAccount>.dfs.core.windows.net/target-folder/", recurse=True)
注意事项
- 服务主体必须在目标Azure租户中注册,而非Databricks所在租户
- 确保为服务主体分配的权限覆盖需要访问/复制的存储容器或文件夹
2. 托管标识(Managed Identity)认证
使用Databricks的托管标识(系统分配或用户分配),在目标租户的存储账户中为该标识分配相应权限:
系统托管标识配置
spark.conf.set("fs.azure.account.auth.type.<storageAccountName>.dfs.core.windows.net", "OAuth") spark.conf.set("fs.azure.account.oauth.provider.type.<storageAccountName>.dfs.core.windows.net", "org.apache.hadoop.fs.azurebfs.oauth2.MsiTokenProvider") spark.conf.set("fs.azure.account.oauth2.client.id.<storageAccountName>.dfs.core.windows.net", "<databricksWorkspaceClientId>") spark.conf.set("fs.azure.account.oauth2.client.endpoint.<storageAccountName>.dfs.core.windows.net", "https://login.microsoftonline.com/<targetTenantId>/oauth2/token") # 复制文件示例 dbutils.fs.cp("abfss://<sourceContainer>@<sourceStorage>.dfs.core.windows.net/", "abfss://<destContainer>@<destStorage>.dfs.core.windows.net/", recurse=True)
用户分配托管标识配置
只需将上述client.id替换为用户分配的托管标识ID即可,其余参数一致。
注意事项
- 需要在目标租户的存储账户中,将Blob数据参与者权限授予Databricks的托管标识
- 若使用系统托管标识,需先获取Databricks工作区的系统托管标识客户端ID
3. SAS令牌(Shared Access Signature)认证
为目标存储的容器或文件夹生成具有读写权限的SAS令牌,通过SAS完成认证:
方式1:通过Spark配置全局生效
spark.conf.set("fs.azure.account.auth.type.<storageAccountName>.dfs.core.windows.net", "SAS") spark.conf.set("fs.azure.sas.token.provider.type.<storageAccountName>.dfs.core.windows.net", "org.apache.hadoop.fs.azurebfs.sas.FixedSASTokenProvider") spark.conf.set("fs.azure.sas.fixed.token.<storageAccountName>.dfs.core.windows.net", "<sasToken>") # 读取并复制 df = spark.read.parquet("abfss://<containerName>@<storageAccountName>.dfs.core.windows.net/folder/") df.write.parquet("abfss://<localContainer>@<localStorage>.dfs.core.windows.net/target-folder/")
方式2:直接在路径中拼接SAS令牌
source_path = f"abfss://<containerName>@<storageAccountName>.dfs.core.windows.net/folder/?<sasToken>" target_path = "abfss://<localContainer>@<localStorage>.dfs.core.windows.net/target-folder/" dbutils.fs.cp(source_path, target_path, recurse=True)
注意事项
- 确保SAS令牌包含足够的权限(至少读取源路径、写入目标路径)
- 注意SAS令牌的有效期,避免过期导致认证失败
内容的提问来源于stack exchange,提问作者Priyanka Saxena
相关产品推荐
相关产品推荐

