J'étudie une erreur qui s'est produite uniquement avec l'opération Put Append dans mon application qui communique avec Azure Blob Service grâce à l'API Rest.Opération Ajouter un bloc avec API Rest Rest Blob - 403 Échec de l'authentification
La création du fichier a réussi mais comme il est un blob append, je devais ajouter du contenu avec Append opération Block et j'obtenir un 403 WebException Interdite lorsque je tente de le faire:
<?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:00dc0116-0001-00c2-066b-cbafe8000000
Time:2017-05-12T22:01:16.1689598Z</Message><AuthenticationErrorDetail>The MAC signature found in the HTTP request 'N7UVKFwftf2YnAFdnciRneu7LsAkWHKXUpwhFRxlQqI=' is not the same as any computed signature. Server used following string to sign: 'PUT
800
x-ms-date:Fri, 12 May 2017 22:01:15 GMT
x-ms-version:2016-05-31
/<myaccount>/write/FixedRecord10r.txt
comp:appendblock'.</AuthenticationErrorDetail></Error>
Cependant, dans la méthode où je construis la signature, j'ai affiché le stringToSign et c'est exactement le même que le serveur utilisé!
PUT
800
x-ms-date:Fri, 12 May 2017 22:01:15 GMT
x-ms-version:2016-05-31
/<myaccount>/write/FixedRecord10r.txt
comp:appendblock
Voici l'en-tête, je paramétrées:
public void AppendFile(MemoryStream stream)
{
string dateFormatted = string.Format(CultureInfo.InvariantCulture, "{0:R}", DateTime.UtcNow);
string signature = GetSignature("PUT", "xxxxxxx", afsAccount, dateFormatted, null, null, stream.Length, null);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://" + afsAccount + ".blob.core.windows.net" + path + "?comp=appendblock");
request.Headers.Add("x-ms-version", "2016-05-31");
request.Headers.Add("x-ms-date", dateFormatted);
request.Headers.Add(HttpRequestHeader.Authorization, "SharedKey " + afsAccount + ":" + signature);
request.Method = "PUT";
request.ContentLength = stream.Length;
using (var requestStream = request.GetRequestStream())
{
stream.Position = 0;
stream.CopyTo(requestStream);
}
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()){
...
}
private String GetSignature(string verb, string azureAccessKey, string afsAccount, string date, string byteRange, string containerName, long contentLength, string blobType)
{
if(byteRange != null)
{
byteRange = "x-ms-range:" + byteRange + "\n";
}
string path = "/" + afsAccount + Dfs.Path;
if (containerName != null)
{
path = "/" + afsAccount + "/" + containerName + "\nrestype:container";
}else if (contentLength > 0)
{
path += " \ncomp:appendblock";
}
string length = "\n";
if (contentLength != 0)
{
length = contentLength.ToString() + "\n";
}
if (blobType != null)
{
blobType = "x-ms-blob-type:" + blobType + "\n";
}
// construct input value
string inputValue = verb + "\n" +
"\n" + /*Content-Encoding*/
"\n" + /*Content-Language*/
length + /*Content-Length*/
"\n" + /*Content-MD5*/
"\n" + /*Content-Type*/
"\n" + /*Date*/
"\n" + /*If-Modified-Since*/
"\n" + /*If-Match*/
"\n" + /*If-None-Match*/
"\n" + /*If-Unmodified-Since*/
"\n" + /*Range*/
blobType +
"x-ms-date:" + date + "\n" +
byteRange +
"x-ms-version:2016-05-31\n" +
path;
Console.WriteLine(inputValue);
// create base64 encoded signature
var hmac = new HMACSHA256();
hmac.Key = Convert.FromBase64String(azureAccessKey);
byte[] sigbyte = hmac.ComputeHash(Encoding.UTF8.GetBytes(inputValue));
var signature = Convert.ToBase64String(sigbyte);
return signature;
}
Je demande maintenant si je raté quelque chose ou s'il y a un problème avec cette opération spécifique que je ne l'ai jamais eu le problème avec d'autres opérations.
J'ai remarqué qu'il y a un espace supplémentaire ici: '{ path + =" \ ncomp: appendblock "; } '(entre' '' et '\ n') .Pouvez-vous supprimer cela et essayer à nouveau votre demande? –
Cet espace supplémentaire était le problème ... Merci beaucoup! – Dragonsen