Closed ghost closed 6 years ago
import time
import uuid
from datetime import datetime, timedelta
import flask
from flask import Flask, request #import main Flask class and request object
from azure.storage.blob import (
BlockBlobService,
ContainerPermissions,
BlobPermissions,
PublicAccess,
)
from azure.storage.common import (
AccessPolicy,
ResourceTypes,
AccountPermissions,
)
def create_container(contName, accName, accKey):
account = BlobService(account_name = accName, account_key = accKey)
account.create_container(contName)
def list_blobs(blockBlobService,contName):
print("\nList blobs in the container")
blobList = blockBlobService.list_blobs(contName)
print(str(blobList))
return blobList
def copy (accFromName, accToName, accFromKey, accToKey, contFromName, contToName, blobName):
blockBlobServiceFrom = BlockBlobService(account_name=accFromName, account_key=accFromKey)
sasToken = blockBlobServiceFrom.generate_container_shared_access_signature(contFromName,ContainerPermissions.READ, datetime.utcnow() + timedelta(hours=1))
blockBloberviceTo = BlockBlobService(account_name=accToName, account_key=accToKey)
sourceBlob = blockBlobServiceFrom.make_blob_url(contFromName, blobName, sas_token=sasToken)
print("###################################>"+sourceBlob)
copied = blockBloberviceTo.copy_blob(contToName, blobName, sourceBlob)
count=0
while copied.status != 'success':
if count > 5:
print('Timed out waiting for async copy to complete.')
time.sleep(30)
copied = blockBloberviceTo.get_blob_properties(contToName, blobName).properties.copy
if copied.status == 'success':
blockBlobServiceFrom.delete_blob(contFromName, blobName)
print("Copy blob: "+blobName+" success! ")
return("Blob "+blobName+" copied!")
else:
print("Copy blob: "+blobName+" failed! "+str(copied.status))
return("Blob "+blobName+" not copied! "+str(copied.status))
app = Flask(__name__) #create the Flask app
@app.route('/ping')
def ping():
version = flask.__version__
return 'Server version: '+ version
@app.route('/copy', methods = ['POST'])
def postJsonHandler():
print (request.is_json)
content = request.get_json()
print (content)
blockBlobServiceFrom = BlockBlobService(account_name=content['storageFromName'], account_key=content['storageFromKey'])
try:
blobList = list_blobs(blockBlobServiceFrom,content['containerFromName'])
for blob in blobList:
message = copy(content['storageFromName'],content['storageToName'],content['storageFromKey'],content['storageToKey'],content['containerFromName'],content['containerToName'],blob.name)
except:
message = "Epty list of blobs!"
return "Copy ended!"
if __name__ == '__main__':
app.run(debug=False, port=5000) #run app in debug mode on port 5000```
Well, you already posted the error:
HTTP status code=403, Exception=Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
You have to be wary of handling URL-quoting correctly when supplying the account key.
Add some debug output and run your copy
function directly and via Flask to see the differences.
Hi @adamsem, thanks for reaching out!
And thanks @Fra-nk for responding!
I agree that logging the credentials out and debug it that way will help narrowing down the problem.
I'm using the same python code (posted as comment) from my VM and from Docker. i'm not changing anything. And from VM works and from Docker is not working. I'm getting only this logs what I posted in ticket. It's some problem with MAC signature in headers. But i'm wondering what is different between VM and docker.
Hi @adamsem, the error log shows that authentication failed for the list blob call. The "MAC signature" is just another way of saying the authentication header. Most often, an authentication failure is caused by using the wrong key to sign the request. It is also possible that there's a bug in the SDK, but since you said the script worked outside of Docker, it sounds unlikely in this case.
To confirm, is this problem reproducible? If yes, could you please log out the account name and key that your postJsonHandler
is getting when running inside Docker? If you can confirm that the credentials used are indeed valid, that would really help in my investigation.
HI @zezha-msft , I solved the problem. That was problem in Flask itself. I change docker image from python 3.5 to python 3.6, after this everything is working fine. Thanks for support.
@adamsem glad to hear that you solved it!
Which service(blob, file, queue) does this issue concern?
BLOB
Which version of the SDK was used? Please provide the output of
pip freeze
.latest
What problem was encountered?
I wrote some app to copy blobs between storage accounts, when i'm run it from local VM everything works fine when I try to run it from docker i'm getting this issue.
Client-Request-ID=3fd7aa82-b044-11e8-8a4b-0242ac110002 Retry policy did not allow for a retry: Server-Timestamp=Tue, 04 Sep 2018 13:13:00 GMT, Server-Request-ID=205bfc1c-e01e-007c-4f51-4480e7000000, HTTP status code=403, Exception=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"?>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.RequestId:205bfc1c-e01e-007c-4f51-4480e7000000Time:2018-09-04T13:13:01.0660872Z The MAC signature found in the HTTP request 'x7XuEX2O63nDYKJwezmgh70SI328U7OpJDq/j8JVe34=' is not the same as any computed signature. Server used following string to sign: 'GETx-ms-client-request-id:3fd7aa82-b044-11e8-8a4b-0242ac110002x-ms-date:Tue, 04 Sep 2018 13:13:01 GMTx-ms-version:2018-03-28//:listrestype:container'.
AuthenticationFailed
Have you found a mitigation/solution?
NOPE
Note: for table service, please post the issue here instead: https://github.com/Azure/azure-cosmosdb-python.