Search code examples
c#azure-active-directoryazure-storageazure-data-lake-gen2azure-identity

Get AccessToken for Azure Storage from InteractiveBrowserCredential


I'm trying to get an accesstoken from a InteractiveBrowserCredential so I can make calls to the Azure Datalake, but when I try to do this I get this error message:

System.Net.Http.HttpRequestException: 'Response status code does not indicate success: 403 (Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.).'

Below is my code, I sspect it might be the scopes I request but I have tried every value I could find online (https://storage.azure.com/user_impersonation, https://storage.azure.com/.default).

// setup authentication
var tenantId = "common";
var clientId = "xxx";               
var options = new InteractiveBrowserCredentialOptions {
    TenantId = tenantId,
    ClientId = clientId,
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,       
    RedirectUri = new Uri("http://localhost"),
};

// authenticate and request accesstoken
var interactiveCredential = new InteractiveBrowserCredential(options);
var token = interactiveCredential.GetToken(new TokenRequestContext(new[] { "https://storage.azure.com/.default" }));

// Create HttpClient            
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Token); ;
string res = await client.GetStringAsync("https://xx.blob.core.windows.net/?comp=list"); // this line throws the error
textBox1.Text = res;

If I use the SDK it does work, so it does not appear to be security settings.

// connect to Azure Data Lake (this works fine)
string accountName = "xxx";
string dfsUri = "https://" + accountName + ".dfs.core.windows.net";
var dataLakeServiceClient = new DataLakeServiceClient(new Uri(dfsUri), interactiveCredential);

// get filesystems 
var systems = dataLakeServiceClient.GetFileSystems().ToList();// works fine

Solution

  • The error "403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signatureerror" usually occurs if you have not x-ms-version header in your code.

    I agree with Gaurav Mantri, To resolve the error make sure to pass header value.

    I tried to reproduce the same in my environment and got the same error as below in Postman:

    enter image description here

    I generated the access token by using the below Parameters:

    https://login.microsoftonline.com/common/oauth2/v2.0/token
    
    grant_type:authorization_code
    client_id:4b08ee93-f4c8-47e9-bb1e-XXXXXXX
    client_secret:client_secret
    scope:https://storage.azure.com/user_impersonation
    redirect_uri:https://jwt.ms
    code: code
    

    enter image description here

    When I included x-ms-version=2019-02-02, I am able to access the storage account successfully like below:

    enter image description here

    The x-ms-version header value must be in the format YYYY-MM-DD.

    In your code, you can include the header below samples:

    Client.DefaultRequestHeaders.Add("x-ms-version", "2019-02-02");
    
    request.Headers.Add("x-ms-version", "2019-02-02");
    

    Reference:

    Versioning for the Azure Storage services | Microsoft Learn