none
Authentication error when using PATCH to write to Azure Data Lake Gen2 RRS feed

  • Question

  • Hello,

    We are using below code to write data to existing file in Azure Data Lake Gen2. However, it returns the error 'Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.'

                string msg2 = string.Format("PATCH\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:{0}\nx-ms-version:2018-11-09\n/datalakename/test/testfolder/testfile1\naction=append&position=0\ntimeout:20", dt);
                byte[] bytes2 = Encoding.UTF8.GetBytes(msg2);
                string authKey2;
                using (HMACSHA256 hmac = new HMACSHA256(data))
                {
                    byte[] hashValue = hmac.ComputeHash(bytes2);
                    authKey2 = Convert.ToBase64String(hashValue);
                }
                var u = await WriteToFileResponse(authKey2, dt);

            private async Task<String> WriteToFileResponse(string hashKey, string date)
            {
                HttpResponseMessage response2;

                //Write content to file
                string url = "https://datalakename.dfs.core.windows.net/test/testfolder/testfile1?action=append&position=0";
                var request = new HttpRequestMessage(new HttpMethod("PATCH"), url);
                request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("SharedKey", string.Format("datalakename:{0}", hashKey));
                request.Headers.Add("x-ms-date", date);
                request.Headers.Add("x-ms-version", "2018-11-09");
                string contentbody = "";
                //request.Content = new StringContent(contentbody, System.Text.Encoding.UTF8, "text/plain");
                request.Content = new StringContent(contentbody);
                //request.Content.Headers.Add("Content-Length", System.Text.ASCIIEncoding.Unicode.GetByteCount(contentbody).ToString());
                //request.Content.Headers.Add("Content-Length", Encoding.UTF8.GetBytes(contentbody).Length.ToString());
                request.Content.Headers.ContentLength.Equals(Encoding.UTF8.GetBytes(contentbody).Length.ToString());
                response2 = await client.SendAsync(request);
                var response2string = await response2.Content.ReadAsStringAsync();

                //var responsewritetofile = await new HttpClient.PatchAsync();
                return response2string;
            }


    We have tried to follow the documentation below, but with no luck yet.

    https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key

    https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/update

    Please suggest.

    Nirav 

    Wednesday, July 24, 2019 8:17 AM

All replies

  • Hi Tutul,

    You can do the same using Oauth2 access token. 

    A simple way to use ADLS Gen2 APIs (Using OAuth2) to create a file would be :

    1. Acquire an Access token by making a POST request to https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token

    Headers :

    "Content-Type: application/x-www-form-urlencoded"

    Body : 

    {"client_id": <CLIENT_ID>,

    "client_secret": <CLIENT_SECRET>,

    "scope" : "https://storage.azure.com/.default",

    "grant_type" : "client_credentials"

    }

    2. Create a file system by making a PUT request to https://<storage account name>.dfs.core.windows.net/<file system name>?resource=filesystem

    Headers :

    Content-Length : 0

    "x-ms-version":"2018-11-09"

    Authorization : Bearer <access_token from step1>

    3. Set default permissions on the root directory by making a PATCH request to  https://<storage account name>.dfs.core.windows.net/<file system name>?action=setAccessControl

    Headers :

    Content-Length : 0

    "x-ms-version":"2018-11-09"

    Authorization : Bearer <access_token from step1>

    x-ms-acl : user::rwx,group::r-x,other::--x,default:user::rwx,default:group::r-x,default:other::--

    4. Create a directory by making a PUT request to https://<storage account name>.dfs.core.windows.net/<file system name>/<directory name>?resource=directory

    Headers :

    Content-Length : 0

    "x-ms-version":"2018-11-09"

    Authorization : Bearer <access_token from step1>

    5. Create a file by making a PUT request tohttps://<storage account name>.dfs.core.windows.net/<file system name>/<directory name>/<file name>?resource=file

    Headers :

    Content-Length : 0

    "x-ms-version":"2018-11-09"

    Authorization : Bearer <access_token from step1>

    To read more, please refer this thread.

    Thursday, July 25, 2019 9:35 AM
    Moderator
  • Hi Tutul,

    Just wanted to check - was your query resolved with the above suggestion? If yes, please consider upvoting and/or marking the above as answer. This would help other community members reading this thread.

    Tuesday, July 30, 2019 8:33 AM
    Moderator