You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PySpark无需账户密钥读取Azure Blob时SAS报错如何解决?

问题原因

不存在无需账户密钥就无法读取Blob数据的情况,你遇到的报错是SAS配置和生成的SAS类型不匹配导致的:你通过generate_blob_sas生成的是单Blob粒度的SAS,而你配置的Spark参数是容器级别的SAS校验位,两者格式要求不匹配,导致Spark无法识别可用凭证。

解决方案

以下两种方案均不需要暴露存储账户密钥:

方案1:修正SAS配置逻辑

  • 如果你要继续用SAS方式,可选择任意一种调整方法:
    1. 改用容器级SAS生成函数:调用generate_container_sas而非generate_blob_sas生成容器级SAS,再填入你现有的Spark配置项即可,生成SAS时可以直接传入你之前使用的DefaultAzureCredential,不需要填存储账户密钥。
    2. 保留现有Blob级SAS的话,不需要单独配置SparkConf,直接把SAS拼接在Blob的访问路径后即可,路径格式为wasbs://<容器名>@<存储账户>.blob.core.windows.net/<Blob路径>?<生成的SAS串>,直接读取该路径即可。
      容器级SAS的配置示例如下:
    from azure.storage.blob import generate_container_sas, ContainerSasPermissions
    from datetime import datetime, timedelta
    import pyspark
    from pyspark.sql import SparkSession
    from azure.identity import DefaultAzureCredential
    
    # 用DefaultAzureCredential生成容器级SAS,全程不需要存储账户密钥
    sas_token = generate_container_sas(
        account_name=storage_account_name,
        container_name=container_name,
        permission=ContainerSasPermissions(read=True, list=True),
        expiry=datetime.utcnow() + timedelta(hours=2),
        credential=DefaultAzureCredential()
    )
    
    spark_conf = pyspark.SparkConf().set(
        f"fs.azure.sas.{container_name}.{storage_account_name}.blob.core.windows.net",
        sas_token
    )
    
    spark = SparkSession.builder \
        .config(conf=spark_conf) \
        .appName("ReadCsvFromBlob") \
        .getOrCreate()
    
    df = spark.read.csv(f"wasbs://{container_name}@{storage_account_name}.blob.core.windows.net/{csv_file_path}")
    

方案2:直接沿用DefaultAzureCredential方案(更推荐)

不需要生成SAS,直接配置Spark用Azure AD身份认证即可,省去SAS过期维护的成本:

from pyspark.sql import SparkSession
import pyspark

spark_conf = pyspark.SparkConf() \
    .set("fs.azure.account.auth.type", "OAuth") \
    .set("fs.azure.account.oauth.provider.type", "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider") \
    .set("fs.azure.account.oauth2.client.id", "<你的Azure AD应用客户端ID>") \
    .set("fs.azure.account.oauth2.client.secret", "<你的Azure AD应用客户端密钥>") \
    .set("fs.azure.account.oauth2.client.endpoint", "https://login.microsoftonline.com/<你的租户ID>/oauth2/token")

spark = SparkSession.builder \
    .config(conf=spark_conf) \
    .appName("ReadCsvFromBlob") \
    .getOrCreate()

# 路径用abfs协议适配AD认证
df = spark.read.csv(f"abfs://{container_name}@{storage_account_name}.dfs.core.windows.net/{csv_file_path}")

如果你是在Azure托管服务(如Databricks、Synapse、绑定了托管标识的AKS节点)上运行,连客户端ID、密钥都不需要配置,直接给托管标识开通Blob读取权限即可,全程不需要任何密钥类敏感信息。

内容的提问来源于stack exchange,提问作者The Questionner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 04:15:08