使用服务主体访问 Azure Blob 存储 [英] Using service principal to access Azure blob storage

查看:16
本文介绍了使用服务主体访问 Azure Blob 存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用来自活动目录服务主体的凭据从 python 访问私有 blob 存储.

I want to access a private blob store, from python, by using credentials from an active directory service principal.

我知道这个相关问题 如何根据 python 中的 Azure 存储 blob 对用户进行身份验证? 这帮助我做到了这一点,但现在我被卡住了.

I am aware of this related question How do I authenticate a user against an Azure storage blob in python? This has helped me get this far but now I'm stuck.

我可以进行身份​​验证并获得一个令牌,它可以让我列出容器、创建新容器,但不会让我列出或访问任何 blob.

I can authenticate and get a token which let me list containers, create new containers, but will not let me list or access any blobs.

我希望通过 az cli 进行设置.

I wish to set this up via the az cli.

服务主体的设置如下:

az ad sp create-for-rbac -n "http://$NAME" --role Contributor 
    --scopes "/subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP" 

我认为应该提供完全访问权限,但我也添加了这个以确保:

Which I believe should give full access but I also added this to be sure:

az role assignment create 
    --role "Storage Blob Data Contributor" 
    --assignee-object-id "$OBJECT_ID" 
    --assignee-principal-type "ServicePrincipal" 
    --scope "/subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Storage/storageAccounts/$STORAGE_ACCOUNT/blobServices/default/containers/$CONTAINER"

然后我像这样进行身份验证:

I am then authenticating like so:

from azure.common.credentials import ServicePrincipalCredentials
import adal
from azure.storage.blob import (
    BlockBlobService,
    ContainerPermissions,
)
from azure.storage.common import (
    TokenCredential
)

# Tenant ID for your Azure Subscription
TENANT_ID = TENANT

# Your Service Principal App ID
CLIENT = APP_ID

# Your Service Principal Password
KEY = PASSWORD

# RESOURCE = "https://storage.azure.com/" # using this resource has the same behaviour as uncommented one. Using no resource fails with authentication errors
RESOURCE = f"https://{ACCOUNT_NAME}.blob.core.windows.net"

credentials = ServicePrincipalCredentials(
    client_id = CLIENT,
    secret = KEY,
    tenant = TENANT_ID,
    resource = RESOURCE
)
tokenCre = TokenCredential(credentials.token["access_token"])

然后我尝试使用 blob 服务

I then try to use the blob service as so

blobService = BlockBlobService(account_name=ACCOUNT_NAME, token_credential=tokenCre)

print ([c.name for c in blobService.list_containers()]) # successfully lists containers
print(blobService.create_container('test')) # prints "True" and the container is created


blobService.list_blobs(CONTAINER_NAME) # fails with AzureHttpError: This request is not authorized to perform this operation using this permission. ErrorCode: AuthorizationPermissionMismatch 

blobService.get_blob_to_bytes("test", "hello.txt") # fails with same error

如上面的代码块所示,我似乎能够执行容器"级别的操作,但不能执行blob"级别的操作.像列出 blob、读取 blob 等任何事情都会出错:

As shown in the code block above I seem to be able to take 'container' level actions but no 'blob' level actions. Any thing like listing blobs, reading a blob etc gets the error:

AzureHttpError: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. ErrorCode: AuthenticationFailed
<?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:86ff0241-c01e-00d4-512c-6e22b5000000
Time:2019-09-18T14:20:23.5619727Z</Message><AuthenticationErrorDetail>Audience validation failed. Audience did not match.</AuthenticationErrorDetail></Error>

有什么想法吗?

推荐答案

如果您想使用 Azure AD 访问令牌来访问您的 Azure 存储,您必须为您的资源分配必要的存储 ** 角色(您在第二次所做的az 命令).

If you want to use Azure AD access token to access your Azure storage, you must assign necessary storage ** role to your resource (which you did in your second az command).

但是,在您的第二个 az 命令中:

However, in your second az command:

az role assignment create 
    --role "Storage Blob Data Contributor" 
    --assignee-object-id "$OBJECT_ID" 
    --assignee-principal-type "ServicePrincipal" 
    --scope "/subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Storage/storageAccounts/$STORAGE_ACCOUNT/blobServices/default/containers/$CONTAINER"

您只需将范围设置为特定容器:$CONTAINER.因此,您只能访问该容器下的 blob.

You only set the scope to a specific container : $CONTAINER. So, you can only access blobs under that container.

我测试了,并且成功了.

I tested, and got a success.

from azure.common.credentials import ServicePrincipalCredentials
import adal
from azure.storage.blob import (
    BlockBlobService,
    ContainerPermissions,
)
from azure.storage.common import (
    TokenCredential
)

# Tenant ID for your Azure Subscription
TENANT_ID = "e4c9****-****-****-****-230b****57fb"

# Your Service Principal App ID
CLIENT = "3bee****-****-****-****-b0b8****f7a4"

# Your Service Principal Password
KEY = "*******************"

ACCOUNT_NAME = "storagetest789"

CONTAINER_NAME = "newcontainer"

RESOURCE = "https://storage.azure.com/"

credentials = ServicePrincipalCredentials(
    client_id = CLIENT,
    secret = KEY,
    tenant = TENANT_ID,
    resource = RESOURCE
)
tokenCre = TokenCredential(credentials.token["access_token"])
blobService = BlockBlobService(account_name=ACCOUNT_NAME, token_credential=tokenCre)

print("
List blobs in the container")
generator = blobService.list_blobs(CONTAINER_NAME)
for blob in generator:
    print("	 Blob name: " + blob.name)

print("
Output test.txt")
blob = blobService.get_blob_to_text(CONTAINER_NAME, "test.txt")
print(blob.content)

结果:

如果我尝试访问其他容器,我将收到与您相同的错误.但我不知道为什么允许容器创建操作.这似乎是对访问控制的疏忽.

If I try to access other containers, I will get the same error as yours. But I don't know why the container create operation is allowed. It seems to be an oversight of access control.

如果要管理整个存储帐户,则需要分配 存储帐户范围到您的服务主体.然后,您可以访问该存储帐户中的其他容器.

If you want to manage the whole storage account, then you need to assign storage account scope to your service principal. Then you can access other containers in that storage account.

这篇关于使用服务主体访问 Azure Blob 存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆