I am using Azure REST API for fetching Billing Usage and Ratecard details. To acquire Token using AcquireToken() Method, initially I used only Client Id which then asks for User Credentials in login window.
However, I am looking for Non-Interactive Approach, so I used Client Credentials in which I passed Client Id and Client Secret Key.
But it gives "Remote Server returns an error 401 Unauthorized"
When I look into error deeply, I found that it gives error "The access token is from wrong audience or resource"
Please give me any solution using which I can access the API without any user interaction.
Thanks in Advance.
Here is my code:
{
string token = GetOAuthTokenFromAAD();
string requestURL = String.Format("{0}/{1}/{2}/{3}",
ConfigurationManager.AppSettings["ARMBillingServiceURL"],
"subscriptions",
ConfigurationManager.AppSettings["SubscriptionID"],
"providers/Microsoft.Commerce/RateCard?api-version=2015-06-01-preview&$filter=OfferDurableId eq 'MS-AZR-*****' and Currency eq 'INR' and Locale eq 'en-IN' and RegionInfo eq 'IN'");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestURL);
request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + token);
request.ContentType = "application/json";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(String.Format("RateCard service response status: {0}", response.StatusDescription));
}
public static string GetOAuthTokenFromAAD()
{
AuthenticationContext authenticationContext = new AuthenticationContext(string.Format("{0}/{1}",ConfigurationManager.AppSettings["ADALServiceURL"], ConfigurationManager.AppSettings["TenantDomain"]));
AuthenticationResult result = null;
ClientCredential uc = new ClientCredential(Client_Id, Secret_Key);
try
{
result = authenticationContext.AcquireToken("https://management.core.windows.net/", uc);
}
return result.AccessToken;
}
//App Config File
<add key="ADALServiceURL" value="https://login.microsoftonline.com" />
<add key="ADALRedirectURL" value="http://*****-authentication.cloudapp.net" />
<add key="ARMBillingServiceURL" value="https://management.core.windows.net" />
<add key="TenantDomain" value="********.onmicrosoft.com" />
<add key="SubscriptionID" value="*******-****-****-****-********" />
<add key="ClientId" value="*******-****-****-****-********" />
Make sure to provide a valid key for an active subscription." "statusCode": 401, "message": "Access denied due to missing subscription key. Make sure to include subscription key when making requests to an API."
The Azure Billing APIs allow you to view and manage your billing details programmatically. Operation groups listed below do not support all billing accounts. Supported billing accounts are specified in the table. To identify your billing account type, see Billing accounts and scopes.
Update: I have also provided these methods as a Reusable Authentication Helper Class Library. You can find the same at this link: Azure Authentication - Authenticating any Azure API Request in your Application
Method 1: To use the password approach non-interactively you need to first follow the below post's section "Authenticate with password - PowerShell": Authenticating a service principal with ARM
Then use the below code snippet to fetch token.
var authenticationContext = new AuthenticationContext(String.Format("{0}/{1}",
ConfigurationManager.AppSettings["ADALServiceURL"],
ConfigurationManager.AppSettings["TenantDomain"]));
var credential = new ClientCredential(clientId: "11a11111-11a1-111a-a111-1afeda2bca1a", clientSecret: "passwordhere");
var result = authenticationContext.AcquireToken(resource: "https://management.core.windows.net/", clientCredential: credential);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
string token = result.AccessToken;
return token;
Alternatively (Method 2), you can also use the certificate method. In that case use the same link as above but follow section "Authenticate with certificate - PowerShell" from that link. Then use the below code snippet to fetch the token non-interactively:
var subscriptionId = "1a11aa11-5c9b-4c94-b875-b7b55af5d316";
string tenant = "1a11111a-5713-4b00-a1c3-88da50be3ace";
string clientId = "aa11a111-1050-4892-a2d8-4747441be14d";
var authContext = new AuthenticationContext(string.Format("https://login.windows.net/{0}", tenant));
X509Certificate2 cert = null;
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
string certName = "MyCert01";
try
{
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates;
var certs = certCollection.Find(X509FindType.FindBySubjectName, certName, false);
//var certs = certCollection.Find(X509FindType.FindBySerialNumber, "E144928868B609D35F72", false);
if (certs == null || certs.Count <= 0)
{
throw new Exception("Certificate " + certName + " not found.");
}
cert = certs[0];
}
finally
{
store.Close();
}
var certCred = new ClientAssertionCertificate(clientId, cert);
var token = authContext.AcquireToken("https://management.core.windows.net/", certCred);
var creds = new TokenCloudCredentials(subscriptionId, token.AccessToken);
//var client = new ResourceManagementClient(creds);
return token.AccessToken;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With