Reputation: 57
The problem summary: Python read from Blob Store using Azure SDK for Python fails on BlockBlobService.get_blob_to_path, with error the the RBAC client I'm using has no attribute called 'signed session', after I've authenticated to Azure AD.
The detail:
I've got read access (as a THIRD PARTY) to an Azure Blob Storage account - using the Azure Active Directory RBAC (Roles Based Access Control). The owners of the Blob store have granted me the role of Storage Blob Data Reader.
The detailed examples I find online for connecting from Python to read from a Blob store use the account_name and account_key parameters - but I do not have those credentials as I do not own the store itself.
I thus found how to use RBAC to connect to Azure - however the read operation itself seems to fail - although I imagine my problem is actually in the step to create the BlockBlobService.
I've created a simplified script to pull a sample of files from the store - based on the files I know I need to download. I seem to be able to connect to Azure Active Directory (disconnecting internet connection confirms failure), but once the read is executed, after some time (~30 seconds), an error is generated as shown below.
Naturally - the redacted sections have the correct credentials / details in my code:
from azure.storage.blob import BlockBlobService
from azure.storage.blob import ContainerPermissions
from azure.graphrbac import GraphRbacManagementClient
from azure.common.credentials import UserPassCredentials
print('Connecting to Azure Active Directory')
credentials = UserPassCredentials(
'[email protected]', # Your user
'zzzzz', # Your password
resource="https://graph.windows.net"
)
tenant_id = "zzzz"
graphrbac_client = GraphRbacManagementClient(
credentials,
tenant_id
)
AccountName = "account_name"
imagesContainer = "container_name"
## Connect to the Azure Block Blob service using the GraphRBAC
print('Connecting to Azure Block Blob Service')
block_blob_service = BlockBlobService(account_name=AccountName, token_credential=graphrbac_client)
All the above seems to run correctly, without any errors or exceptions. However, as soon as I run the code below - then I get the error below:
block_blob_service.get_blob_to_path(imagesContainer, AzureFilename, newFileName)
Exception has occurred: azure.common.AzureException
'GraphRbacManagementClient' object has no attribute 'signed_session'
File "C:\zzz\PullUnsortedImagesFromAzure.py", line 138, in <module>
block_blob_service.get_blob_to_path(imagesContainer, AzureFilename, newFileName)
File "C:\Python\Python37\Lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Python\Python37\Lib\runpy.py", line 96, in _run_module_code
mod_name, mod_spec, pkg_name, script_name)
File "C:\Python\Python37\Lib\runpy.py", line 263, in run_path
pkg_name=pkg_name, script_name=fname)
What is interesting is that in Windows Explorer, I can actually see the file being created - but it doesn't actually get pulled from Blob store.
I'm really no expert when it comes to AD - so I'm guessing, but I imagine the issue is probably originating from:
block_blob_service = BlockBlobService(account_name=AccountName, token_credential=graphrbac_client)
I would be extremely grateful if anyone could help point out what I should be doing...
Thank you!
Upvotes: 0
Views: 973
Reputation: 15609
You can follow the steps as below to authenticate an application to access the storage blob.
1.Register an application in Azure portal.
Click the app you just registered.
Click Settings->click keys->input a description for the key->click save. The value of the key is client secret.
2.Grant the permissions to your application.
3.access storage resource
import adal
from azure.storage.blob import (
BlockBlobService,
ContainerPermissions,
)
from azure.storage.common import (
TokenCredential
)
RESOURCE = "https://storage.azure.com/"
clientId = "***"
clientSecret = "***="
tenantId = "***"
authority_url = "https://login.microsoftonline.com/" + tenantId
print(authority_url)
context = adal.AuthenticationContext(authority_url)
token = context.acquire_token_with_client_credentials(
RESOURCE,
clientId,
clientSecret)
print(token)
tokenCre = TokenCredential(token["accessToken"])
blobService = BlockBlobService(account_name="***", token_credential=tokenCre)
Upvotes: 1