Get AccessToken for Azure Storage from InteractiveBrowserCredential - c#

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

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:
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
When I included x-ms-version=2019-02-02, I am able to access the storage account successfully like below:
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

Related

Azure Function App w/ 0Auth error - ERROR: AADSTS500011: The resource principal named

I need to add 0Auth to my Azure Function App, which will be triggered through HTTP request, POST, and I should retrieve the user details that I pass the credentials into the body. I'm quite newbie on coding, and all tutorials I have seen so far, due my unexeperience, it is a just bunch of non-sense code for me with many details that in my point of view just someone with experience would be able to follow. I was able to generate my token, but not pass it together in my request, also when I call the API it is throwing me the following error:
Parameters: Connection String: [No connection string specified], Resource: http://localhost:7235/api/.default, Authority: . Exception Message: Tried to get token using Azure CLI. Access token could not be acquired. ERROR: AADSTS500011: The resource principal named http://localhost:7235/api/.default was not found in the tenant named <CN>. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.
As a Token Provider, I'm using the class AzureServiceTokenProvider();, which I believe is causing this error. I looked for some alternatives for Token Providers, and I could find only the TokenProver(); but I tried to use some of them and I was getting errors as well. I was requested to do everything using C# and nothing else, not the Portal Azure. The onlu thing I can use from Azure is the Azure Storage Account. I was able to create the "CRUD" system, and they are working fine. I don't have any more class related with token.
This is my code below:
public static async Task<IActionResult> Login(
[HttpTrigger(AuthorizationLevel.Admin, "POST", Route = "login")] HttpRequest req,
[Table("User", Connection = "AzureWebJobsStorage")] TableClient tdClient,
ILogger log)
{
string url = "http://localhost:7235/api/.default";
var httpClient = new HttpClient();
var azureServiceTokenProvider = new AzureServiceTokenProvider();
string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync(url);
var requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var input = JsonConvert.DeserializeObject<CreateUserDto>(requestBody);
var user = new User
{
email = input.email,
password = input.password
};
string userToString = user.ToString();
var stringContent = new StringContent(userToString, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(url, stringContent).ConfigureAwait(false);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
return new OkObjectResult(response);
}
I really don't want to use the AzureServiceTokenProvider(); class. Is it possible to do that using the TokenProvider();. How can I do that? I hope I made myself clear. Thanks.
If you want to enforce authentication you should consider Azure Function/App Service Authentication or
https://learn.microsoft.com/en-us/azure/azure-functions/security-concepts?tabs=v4#enable-app-service-authenticationauthorization

Issues Accessing Microsoft Graph API Data

Currently having issues integrating Microsoft Graph API, into my ASP.NET Core 2.2 Web Application(MVC). That uses "Work or Schools Accounts" : “Cloud – Single Organisation” using Two Factor Azure Sign-on Authentication.
Using Code Sample 1 code I'm attempting to GET the graph query: -
https://graph.microsoft.com/v1.0/me/
returning the surname from the response header
The issue that i'm experiencing at the moment is that i'm receiving an error at the line of code: -
var objMessages = objGraphClient.Me.Request().GetAsync().Result;
With the error message : "does not exist or one of its queried reference-property objects are not present".
// #############
// Code Sample 1
// #############
// Graph Api.
string strResource = "https://graph.microsoft.com";
string SecretId = "<Secret Id>";
// Azure Ad.
Uri strInstance = new Uri("https://login.microsoftonline.com/");
string strDomain = "<Domain>.onmicrosoft.com";
string strTenantId = "<Tenant Id>";
string strClientId = "<Client Id>";
string strCallbackPath = "/signin-oidc";
// The authority to ask for a token: your azure active directory.
string strAuthority = new Uri(strInstance, strTenantId).AbsoluteUri;
AuthenticationContext objAuthenticationContext = new AuthenticationContext(strAuthority);
ClientCredential objClientCredential = new ClientCredential(strClientId, SecretId);
// Acquire Token.
AuthenticationResult objAuthenticationResult = objAuthenticationContext.AcquireTokenAsync(strResource, objClientCredential).Result;
// Get bearer token.
GraphServiceClient objGraphClient = new GraphServiceClient(new DelegateAuthenticationProvider(
async request =>
{
// This is adding a bearer token to the httpclient used in the requests.
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", objAuthenticationResult.AccessToken);
}));
// The next line produces an error :: does not exist or one of its queried reference-property objects are not present.
var objResult = objGraphClient.Me.Request().GetAsync().Result;
Debug.WriteLine($"{objResult.Surname}");
If I change Code Sample 1 above to Code Sample 2 below passing in the tokenPlease() requested that’s obtained from Microsoft Graph Explorer after successful login, this works, returning the surname successfully, indicating that their is an issue possible in my Bearer token: -
// #############
// Code Sample 2
// #############
// Get bearer token.
GraphServiceClient objGraphClient = new GraphServiceClient(new DelegateAuthenticationProvider(
async request =>
{
// This is adding a bearer token to the httpclient used in the requests.
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer","ERf54f2f...Etc");
}));
// The next line now works.
var objResult = objGraphClient.Me.Request().GetAsync().Result;
Debug.WriteLine($"{objResult.Surname}");
Any help on this would be much appreciated!
You are using the ADAL library which uses the old Azure AD V1 authentication endpoint. You should be using the MSAL Library which uses the Azure AD V2 authentication endpoint.
I would suggest making your life easy and go grab the Microsoft.Graph.Auth Nuget package and then use this code instead of having to create your own
DelegateAuthenticationProvider
IConfidentialClientApplication clientApplication = AuthorizationCodeProvider.CreateClientApplication(clientId, redirectUri, clientCredential);
AuthorizationCodeProvider authenticationProvider = new AuthorizationCodeProvider(clientApplication, scopes);

Fetch user details from Azure AD

I am trying to fetch users' details from Azure AD using Graph API.
My code is like this :
public B2CGraphClient(string clientId, string clientSecret, string tenant)
{
this.clientId = clientId;
this.clientSecret = clientSecret;
this.tenant = tenant;
this.authContext = new AuthenticationContext("https://login.microsoftonline.com/" + tenant);
this.credential = new ClientCredential(clientId, clientSecret);
}
public string GetUserByObjectId(string objectId)
{
return SendGraphGetRequest("/users/" + objectId);
}
public string SendGraphGetRequest(string api)
{
AuthenticationResult result = authContext.AcquireToken("https://graph.windows.net", credential);
HttpClient http = new HttpClient();
string url = "https://graph.windows.net/" + tenant + api + "?" + "api-version=1.6";
}
But i am gettign an exception at AcquireToken line in SendGraphGetRequest method as -
Error validating credentials. Invalid client secret is provided
Inner Exception is :{"The remote server returned an error: (401) Unauthorized."}
I have provided both - Client ID and Client secret Key, But still getting this exception.
What am I missing here?
Based on the error message, the secret is incorrect. You can regenerate a new secret on Azure portal and use the new secret to fix this issue.
If you're sure that the secret is correct, then make sure that the Application you've registered to use as the service principal has been assigned rights:
This particular permission requires that you get approval from an AAD administrator before access is granted.
From the AAD Documentation:
Request the permissions from a directory admin
When you're ready to request permissions from the organization's admin, you can redirect the user to the v2.0 admin consent endpoint.
// Line breaks are for legibility only.
GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions
// Pro tip: Try pasting the following request in a browser!
https://login.microsoftonline.com/common/adminconsent?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&state=12345&redirect_uri=http://localhost/myapp/permissions

InstaSharp: Can not get the access token

I am using InstaSharp in a WPF application. I have read the documentation of InstaSharp. And here is the code I tried.
InstagramConfig config = new InstagramConfig(clientId, clientSecret, redirectUri, realtimeUri);
var oAuth = new OAuth(config);
var scopes = new List<OAuth.Scope>();
var link = InstaSharp.OAuth.AuthLink(config.OAuthUri + "authorize", config.ClientId, config.RedirectUri, scopes, InstaSharp.OAuth.ResponseType.Code);
var authInfo = await oAuth.RequestToken(clientId);
Now the problem is that I am getting authInfo as null. Which means I am getting the accesstoken as null. When I copy paste the link(generated by above code) in the browser, it asks me for authorization and generates an access token but I can not get it programmatically with the above code.
Can someone please help me get the access token ?

Use Dropbox access token without going through the authorization flow

I've got a Generated access token from DropBox ".....fquCiA_pW5SsJal2C.......".
I'm using the following code to upload a file-
static void Main()
{
// Uncomment the following line or manually provide a valid token so that you
// don't have to go through the authorization process each time.
//var accessToken = GetAccessToken();
// var accessToken = new OAuthToken("token", "secret");
var api = new DropboxApi(ConsumerKey, ConsumerSecret, accessToken);
var file = api.UploadFile("dropbox", #"myFolder\b.jpg", #"b.jpg");
Console.WriteLine(string.Format("{0} uploaded.", file.Path));
}
There is an instruction in the code that I can use a token. So, I have used-
var accessToken = "...lkasjdfsdlfjsadlj...";
But it shows invalid argument error. Where shall I use that key?
Please help?
I've taken the code from here

Categories