Azure / Azure/azure-storage-python
BlockBlobService inconsistent handling of container SAS URLs and tokens, particularly those generated by make_container_url
- Lenguaje dominante
- Python
- Estrellas
- 343
- Forks
- 243
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Descripción
### Which service(blob, file, queue) does this issue concern?
Blob
### Which version of the SDK was used? Please provide the output of `pip freeze`.
azure-storage-blob==1.4.0
### What problem was encountered?
There seems to be an inconsistency in how SAS's are generated and managed in the Python SDK.
First let me give a bit of background about my use case. Basically, we have folks providing us a SAS to one of their containers, which we then will upload some files to. They provide the SAS to us as one big URL, that is to say something which looks like this:
`https://.blob.core.windows.net/?se=2019-01-16T22%3A26%3A51Z&sp=w&sv=2018-03-28&sr=c&sig=`
If I generate a SAS in Python like so I get a value which looks just like the query string in my sample above:
```
sas = blob_service.generate_container_shared_access_signature(
container_name=container_name,
permission=azure.storage.blob.ContainerPermissions(write=True),
expiry=(datetime.datetime.utcnow() + datetime.timedelta(hours=3)))
```
But since the URL provided to me needs to also include the container name, etc, I use `blob_service.make_container_url(container_name, sas_token=sas)` to create a URL. This URL looks a bit different than I expect:
`https://.blob.core.windows.net/?restype=container&se=2019-01-16T22%3A26%3A51Z&sp=w&sv=2018-03-28&sr=c&sig=` - specifically it's got this extra `restype=container` in it.
Later, when I want to actually perform a file upload using the provided URL, I have a few options.
1. I can construct a `BlockBlobService` like this (using the full URL):
`blob_service = azure.storage.blob.BlockBlobService(account, sas_token='https://.blob.core.windows.net/?restype=container&se=2019-01-16T22%3A26%3A51Z&sp=w&sv=2018-03-28&sr=c&sig=')`
2. or like this (using just the query string):
`blob_service = azure.storage.blob.BlockBlobService(account, sas_token='restype=container&se=2019-01-16T22%3A26%3A51Z&sp=w&sv=2018-03-28&sr=c&sig=')`
Number 2 above doesn't work, because of the `restype=container`. Number 1 works, but _only if the sas URL contains `restype=container`_ - if somebody provides a URL generated from say the C# SDK which doesn't have `restype=container` I end up getting the following error when trying to use the SAS:
```
azure.common.AzureHttpError: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. ErrorCode: AuthenticationFailed
AuthenticationFailedServer failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:72c1719b-201e-0054-078a-ae25a1000000
Time:2019-01-17T17:31:25.7442116ZAccess without signed identifier cannot have time window more than 1 hour: Start [Thu, 17 Jan 2019 17:31:25 GMT] - Expiry [Thu, 17 Jan 2019 19:29:18 GMT]
```
Reading the documentation from the Python SDK, it seems like the `sas_token` parameter of `BlockBlobService` is supposed to just be the SAS token (i.e. this bit: `se=2019-01-16T22%3A26%3A51Z&sp=w&sv=2018-03-28&sr=c&sig=` - but the problem is that when presented with a full URL containing `restype=container` in the query string, it's not clear to me how to pull out "just the SAS" given an arbitrary query string. What I had been doing was to use the full query string as the SAS, but since `restype=container` is valid in the query string, but also not valid in the SAS token I'm now at a loss as to how to properly extract the SAS.
**To summarize, my questions/issues are:**
1. Why does `blob_service.make_container_url` include `restype=container` in the URL? The URL generated already clearly points to a container so it seems like this extra `restype=container` is not useful.
2. Given a URL like `https://.blob.core.windows.net/?restype=container&se=2019-01-16T22%3A26%3A51Z&sp=w&sv=2018-03-28&sr=c&sig=` how can I extract just the sas part, so that I can then pass that to the `BlockBlobService` constructor as the `sas_token` parameter?
3. Why does `BlockBlobService` accept a full URL as the `sas_token`, but it _only works_ if that full URL contains `restype=container`?
4. Is the intent of the `sas_token` in `BlockBlobService` that it accepts both a full URL or the bare SAS token, or should it accept only the token?
### Have you found a mitigation/solution?
The only mitigation/solution I've found is to tell people to avoid using `make_container_url` entirely, and to generate their URLs manually - which isn't really a great solution.
Guía de contribución
Línea de trabajo
Start with the BlockBlobService constructor and the make_container_url and generate_container_shared_access_signature entry points described in the issue. Trace how full SAS URLs and bare query-string tokens are parsed, especially the restype=container parameter. Done means the intended sas_token input forms are clear and consistent for URLs generated by this SDK and other SDKs, with the reported authentication behavior addressed.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- python
- Área
- cloud
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 35/100