使用SAS令牌连接Azure DataLakeServiceClient认证失败求助
问题描述
编写自动化脚本检查Azure DataLake指定目录内容时,遇到以下问题:
- 使用
DataLakeServiceClient连接时认证失败,报错:Server failed to authenticate the request...The specified signed resource is not allowed for the this resource level - 同一SAS令牌可在Microsoft Azure Storage Explorer正常使用,也能通过
DataLakeFileClient连接(需指定容器名和文件路径) DataLakeFileClient和DataLakeDirectoryClient无法列出目录及子目录下的所有文件
环境信息
- Python版本:3.7.9
- Azure存储库版本:azure-storage-file-datalake 12.9.0
代码示例
from azure.storage.filedatalake import DataLakeServiceClient url_with_sas = "https://<account_name>.blob.core.windows.net/<container_name>?sp=racwdlmeop&st=2022-10-17T11:50:11Z&se=2022-10-17T19:50:11Z&spr=https&sv=2021-06-08&sr=c&sig=<some_hash>" account_url = 'https://<account_name>.blob.core.windows.net/' sas_token = '?sp=racwdlmeop&st=2022-10-17T11:50:11Z&se=2022-10-17T19:50:11Z&spr=https&sv=2021-06-08&sr=c&sig=<some_hash>' client = DataLakeServiceClient(account_url, sas_token) # 尝试过直接用包含SAS的URL创建,返回错误: # azure.core.exceptions.HttpResponseError: The requested URI does not represent any resource on the server. # client = DataLakeServiceClient(url_with_sas) print(client.get_service_properties())
报错信息
Traceback (most recent call last): File "C:/Users/plewkak/OneDrive - ZF Friedrichshafen AG/Desktop/IDA-automation-tool/aaaaa.py", line 13, in <module> print(client.get_service_properties()) File "C:\Users\plewkak\AppData\Local\Programs\Python\Python37\lib\site-packages\azure\storage\filedatalake\_data_lake_service_client.py", line 569, in get_service_properties props = self._blob_service_client.get_service_properties(**kwargs) # pylint: disable=protected-access File "C:\Users\plewkak\AppData\Local\Programs\Python\Python37\lib\site-packages\azure\core\tracing\decorator.py", line 78, in wrapper_use_tracer return func(*args, **kwargs) File "C:\Users\plewkak\AppData\Local\Programs\Python\Python37\lib\site-packages\azure\storage\blob\_blob_service_client.py", line 310, in get_service_properties process_storage_error(error) File "C:\Users\plewkak\AppData\Local\Programs\Python\Python37\lib\site-packages\azure\storage\blob\_shared\response_handlers.py", line 185, in process_storage_error exec("raise error from None") # pylint: disable=exec-used # nosec File "<string>", line 1, in <module> azure.core.exceptions.ClientAuthenticationError: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:ab2261e5-101e-0053-1924-e2b0ce000000 Time:2022-10-17T12:34:45.3304352Z ErrorCode:AuthenticationFailed authenticationerrordetail:The specified signed resource is not allowed for the this resource level Content: <?xml version="1.0" encoding="utf-8"?><Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:ab2261e5-101e-0053-1924-e2b0ce000000 Time:2022-10-17T12:34:45.3304352Z</Message><AuthenticationErrorDetail>The specified signed resource is not allowed for the this resource level</AuthenticationErrorDetail></Error> Process finished with exit code 1
解决方案
1. 问题根源:SAS令牌资源级别不匹配
你的SAS令牌参数中sr=c表示这是容器级SAS,仅能用于容器或容器内的资源操作,无法用于服务级操作(比如DataLakeServiceClient的get_service_properties是服务级API),这就是认证失败的核心原因。
2. 正确的客户端选择
使用DataLakeFileSystemClient(对应Azure DataLake的容器/文件系统)进行操作,它适配容器级SAS的权限范围。
3. 代码实现:列出目录及子目录所有文件
from azure.storage.filedatalake import DataLakeFileSystemClient # 直接使用包含容器和SAS的URL创建FileSystemClient url_with_sas = "https://<account_name>.blob.core.windows.net/<container_name>?sp=racwdlmeop&st=2022-10-17T11:50:11Z&se=2022-10-17T19:50:11Z&spr=https&sv=2021-06-08&sr=c&sig=<some_hash>" file_system_client = DataLakeFileSystemClient.from_connection_string(url_with_sas) # 指定要检查的目录路径,递归列出所有文件和子目录 target_directory = "your-target-directory-path" all_paths = file_system_client.get_paths(path=target_directory, recursive=True) # 遍历输出所有路径 for path in all_paths: # 区分文件和目录 if path.is_directory: print(f"目录: {path.name}") else: print(f"文件: {path.name}")
关键说明
get_paths方法的recursive=True参数会递归遍历所有子目录,返回该目录下的所有文件和目录路径,解决无法列出子目录文件的问题。- 容器级SAS无法用于服务级操作,因此不要尝试用它创建
DataLakeServiceClient,所有操作应限定在容器范围内。
内容的提问来源于stack exchange,提问作者Leonek
相关产品推荐
相关产品推荐

