List Storage Accounts only listing a few classic storage accounts - rest

List Storage Accounts https://management.core.windows.net//services/storageservices
says that it lists the storage accounts that are available in the specified subscription and the get storage account keys work only for these storage accounts that are returned as part of this call.
But the response is giving me only few storage accounts which are classic, how do i get the other storage accounts?

But the response is giving me only few storage accounts which are
classic, how do i get the other storage accounts?
By "other" storage accounts, I guess you're meaning "Azure Resource Manager (ARM)" storage accounts. There's a different API to get ARM storage accounts that make use of Azure AD based authentication.
To learn more about ARM API to list storage accounts, please see this link: https://learn.microsoft.com/en-us/rest/api/storagerp/storageaccounts#StorageAccounts_List.
To learn more about how to authenticate/authorize ARM API calls, please see this link: https://learn.microsoft.com/en-us/rest/api/

I agree with Gaurav Mantri, if you’d like to list ARM storage accounts under a specified subscription, please use this API:
GET https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Storage/storageAccounts?api-version=2016-12-01
And the following code sample works fine on my side, please refer to it.
string tenantId = "{tenantId}";
string clientId = "{clientId}";
string clientSecret = "{secret}";
string subscriptionid = "{subscriptionid}";
string authContextURL = "https://login.windows.net/" + tenantId;
var authenticationContext = new AuthenticationContext(authContextURL);
var credential = new ClientCredential(clientId, clientSecret);
var result = await authenticationContext.AcquireTokenAsync(resource: "https://management.azure.com/", clientCredential: credential);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
string token = result.AccessToken;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(string.Format("https://management.azure.com/subscriptions/{0}/providers/Microsoft.Storage/storageAccounts?api-version=2016-12-01", subscriptionid));
request.Method = "GET";
request.Headers["Authorization"] = "Bearer " + token;
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
//extract data from response
}
catch (WebException ex)
{
//ex.Message;
}
Besides, this article explained how to create AD application and service principal that can access resources, please refer to it.

Thanks for your response,by other storage accounts I meant the storage accounts under the classic storage accounts itself which were not getting listed.
Instead of using
https://management.core.windows.net//services/storageservices
I used the REST API's
for the new storage accounts
/management.azure.com/subscriptions/id/providers/Microsoft.Storage/storageAccounts?api-version=2016-12-01
for classic:
/management.azure.com/subscriptions//providers/Microsoft.ClassicStorage/storageAccounts?api-version=
and to get keys
/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/listKeys?api-version=2016-12-01
/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ClassicStorage/storageAccounts/{accountName}/listKeys?api-version=2016-11-01

Related

DefaultAzureCredential: Graph access forbidden with VisualStudio Code Credential

I'm trying to read user properties from ms graph inside an Azure function.
For authentication I used the DefaultAzureCredential class from Azure.Identity.
Access with Shared Token Cache Credential locally and Managed Identity Credential in Azure is no prob!
I wanted to use the Visual Studio Code Credential, but I get an "Authorization_RequestDenied! Insufficient privileges to complete the operation" error message when I call the graph API.
The problem seems to be the access token I received with the VS Code Credential. The user account is the same one I used with the Shared Token Cache Credential.
Any ideas? Thank you.
Code:
DefaultAzureCredentialOptions options = new DefaultAzureCredentialOptions();
options.VisualStudioCodeTenantId = Environment.GetEnvironmentVariable("Debug_VisualStudioCodeTenantId");
var credential = new DefaultAzureCredential(options);
token = credential.GetToken(
new Azure.Core.TokenRequestContext(
new[] { "https://graph.microsoft.com/.default" }));
accessToken = token.Token;
var graphServiceClient = new GraphServiceClient(
new DelegateAuthenticationProvider((requestMessage) =>
{
requestMessage
.Headers
.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
return Task.CompletedTask;
}));
var users = await graphServiceClient.Users.Request().GetAsync(); // throw the forbidden exception
Exception:
"Code: Authorization_RequestDenied\r\nMessage: Insufficient privileges to complete the operation.\r\nInner error:\r\n\tAdditionalData:\r\n\tdate: 2021-04-20T08:02:23\r\n\trequest-id: ...\r\n\tclient-request-id: ...\r\nClientRequestId: ...\r\n"
After inspecting the token returned by VS Code, it seems to be missing a required delegated permission/scope.
The docs say one of these is required to list users:
User.ReadBasic.All, User.Read.All, User.ReadWrite.All, Directory.Read.All, Directory.ReadWrite.All, Directory.AccessAsUser.All
Since the service principal that VS Code is using does not require any of these, it won't work.
After trying to explicitly get the token with the required scope, it doesn't seem to work either.
So the VS Code credential currently just doesn't seem to work for this purpose.
You'll need a different credential or perhaps use the client secret/certificate credential with your own app registration.

Get access token on Microsoft federated accounts

I'm trying to get access token for Power BI API. Our account is a federated account.
I've been trying this but it keeps giving me an error saying Incorrect username or password. To use the resource owner password credentials grant flow to get the access token for Azure AD, I make a call to http request diectly using the HttpClient
HttpClient clie = new HttpClient();
string tokenEndpoint = "https://login.microsoftonline.com/{tenant}/oauth2/token";
var body = "resource=https://analysis.windows.net/powerbi/api&client_id={client_id}&grant_type=password&username={username}&password={password}";
var stringContent = new StringContent(body, Encoding.UTF8, "application/x-www-form-urlencoded");
string result = clie.PostAsync(tokenEndpoint, stringContent).ContinueWith((response) =>
{
return response.Result.Content.ReadAsStringAsync().Result;
}).Result;
This will work for non federated accounts. How can I implement the same for federated accounts?
The easier would be to leverage MSAL.NET (or ADAL.NET) which does a lot to achieve that. See https://aka.ms/msal-net-up
scopes = new string[]{ "https://analysis.windows.net/powerbi/api/Dashboard.Read.All"}
result = await app.AcquireTokenByUsernamePasswordAsync(scopes, "joe#contoso.com",
securePassword);
Even better if you know that your machine is domain joined or AAD joined, you can use Integrated Windows Authentication: https://aka.ms/msal-net-iwa
result = await app.AcquireTokenByIntegratedWindowsAuthAsync(scopes);
Note that, I recommend using MSAL.NET (instead of ADAM.NET), because with MSAL/NET/the Azure AD v2.0 endpoint, PowerBI offers a better control of the permission scopes:
See the API permissions tab in an app registration in https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview

Azure IOT Hub Rest API Unauthorized

I am trying to use Azure Iot hub REST API to create device by following links
Create a new device identity
Control access to IoT Hub
And my http data is like
{
"status":"connected",
"authentication":{ "symmetricKey":{
"primaryKey":"key in shared access policies",
"secondaryKey":"key in shared access policies"}
},
"statusReason":"reason",
"deviceId":"test123"
}
My header is like
["Content-Type": "application/json", "Authorization": "SharedAccessSignature sig=(key in shared access policies public key)=&se=1481687791&skn=iothubowner&sr=(my iot hub name).azure-devices.net%2fdevices%2ftest123"]
But i get error 401
{"Message":"ErrorCode:IotHubUnauthorizedAccess;Unauthorized","ExceptionMessage":"Tracking ID:(tracking id )-TimeStamp:12/14/2016 03:15:17"}
Anyone know how to fixed it , or to track the exceptionMessage ?
The problem of 401 is, probably, in the way you are calculating the SAS.
The full process to calculate a SAS for the IoT Hub (in C#) is:
private static readonly DateTime epochTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
public static string SharedAccessSignature(string hostUrl, string policyName, string policyAccessKey, TimeSpan timeToLive)
{
if (string.IsNullOrWhiteSpace(hostUrl))
{
throw new ArgumentNullException(nameof(hostUrl));
}
var expires = Convert.ToInt64(DateTime.UtcNow.Add(timeToLive).Subtract(epochTime).TotalSeconds).ToString(CultureInfo.InvariantCulture);
var resourceUri = WebUtility.UrlEncode(hostUrl.ToLowerInvariant());
var toSign = string.Concat(resourceUri, "\n", expires);
var signed = Sign(toSign, policyAccessKey);
var sb = new StringBuilder();
sb.Append("sr=").Append(resourceUri)
.Append("&sig=").Append(WebUtility.UrlEncode(signed))
.Append("&se=").Append(expires);
if (!string.IsNullOrEmpty(policyName))
{
sb.Append("&skn=").Append(WebUtility.UrlEncode(policyName));
}
return sb.ToString();
}
private static string Sign(string requestString, string key)
{
using (var hmacshA256 = new HMACSHA256(Convert.FromBase64String(key)))
{
var hash = hmacshA256.ComputeHash(Encoding.UTF8.GetBytes(requestString));
return Convert.ToBase64String(hash);
}
}
If you want to create the device in the IoTHub you have to have a policy with full permissions that mean:
Registry read and write, Service connect and Device connect.
If you need a full functional example, in C#, about how use the IoT Hub REST API to create a device, check if a device exists and send messages to the IoT Hub I have wrote this post about it (the post is in spanish but I can imagine that what you need is just the code).
it looks like your SAS is wrong. It shouldn't include the devices part in the end. If you open the Iot Hub Device Explorer you can Generate SAS token to access the Iot Hub API. You should create the SAS for the IoT hub level and for a device level (which include the devive id in the SAS like you have).
So your SAS should look like this -
SharedAccessSignature sr={iot hub name}.azure-devices.net&sig={sig}&se={se}&skn=iothubowner
There are two edits you need to do:
In your http data, only deviceId is required, other are optional, you can do it like this:
{
deviceId: "test123"
}
Note that there are no double quotes around deviceId.
Like #shachar said, you need remove "%2fdevices%2ftest123" in SAS token of the header. About generating SAS token you can utilize Device Explorer.
This is my test result:
The format of SAS token you use is wrong. To create a device, you need to use SAS Token for IoT Hub. You could easily use Azure IoT Toolkit extension for Visual Studio Code to generate SAS Token for IoT Hub as below screenshot.
BTW, the format of SAS token for device is /^SharedAccessSignature sr=iot-hub-test.azure-devices.net%2Fdevices%2Fdevice1&sig=.+&se=.+$/, while the format of SAS token for IoT Hub is /^SharedAccessSignature sr=iot-hub-test.azure-devices.net&sig=.+&skn=iothubowner&se=.+$/
//Following code is to generate the SAS token programatically.
string sasToken = new SharedAccessSignatureBuilder()
{ KeyName = name,
Key = key,
Target = target,
TimeToLive = TimeSpan.FromDays(days)
}.ToSignature();
//use this sas token as authorization header before calling the iot restapi

rest api unauthorized Azure Data Catalog

I am using Azure Data Catalog of my organization. I am not creator/administrator/owner of the Catalog but I have access to register/delete catalogs from the web interface.
I want to use rest API for Azure Data Catalog. Is it possible with my level of permission?
I have followed all the steps from https://msdn.microsoft.com/en-us/library/mt428033.aspx and written the following piece of code:
class Program
{
static void Main(string[] args)
{
string url = "https://api.azuredatacatalog.com/catalogs/DefaultCatalog/search/search?searchTerms=My_Server&count=10&startPage=1&api-version=2016-03-30";
HttpWebRequest request = System.Net.WebRequest.Create(url) as System.Net.HttpWebRequest;
Console.WriteLine(AccessToken().CreateAuthorizationHeader());
try
{
WebResponse response = request.GetResponse();
Console.WriteLine(response.ContentLength);
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.ReadKey();
}
static AuthenticationResult AccessToken()
{
string resourceUri = "https://datacatalog.azure.com";
string clientId = "my-client-id";
string redirectUri = "my-redirect-uri";
string authorityUri = "https://login.windows.net/common/oauth2/authorize";
AuthenticationContext authContext = new AuthenticationContext(authorityUri);
return authContext.AcquireToken(resourceUri, clientId, new Uri(redirectUri), PromptBehavior.RefreshSession);
}
}
and when I try to run the search from API, I get the following error:
System.Net.WebException: The remote server returned an error: (401)
Unauthorized. at System.Net.HttpWebRequest.GetResponse() at
HRBIADCAPI.Program.Main(String[] args) in
c:\users\naghimir\documents\visual studio
2015\Projects\HRBIADCAPI\HRBIADCAPI\Program.cs:line 32
Now I think the problem is that I have not given access to the client program created to read/write data catalog (that I did in Azure Data Factory) but that step is not there in the documentation either.
Do I need to be the owner or can I request permission from the owner to use Azure Data Catalog API?
Based on the description, you were using the OAuth 2.0 code grant flow to grant the app to delegate the user to manipulate the Azure Data Catalog.
To ensure the request works well, we need to grant the scope to the app like figure below:
And since the app only delegate the users’ permission, please ensure that user have the sufficient permission to operate the resource manfully.

Retrieving IPP access token and access secret from paypal callback

I have a web app that uses a standard paypal shopping cart. What we want to do is to automatically record payments in QB online using Intuit QB API when paypal notifies our web site that the payment has completed.
The examples I have seen for obtaining the access token and secret are user-initiated. How can I get these inside the context of this paypal callback? I need them to happen automatically, and without a Request context from a user. I have some basic test code here that runs within the paypal callback.
//start a transaction
//start try block
//set our transaction record as paid
Token = ConfigurationManager.AppSettings["appToken"];
string consumerKey = ConfigurationManager.AppSettings["consumerKey"];
string consumerSecret = ConfigurationManager.AppSettings["consumerSecret"];
string companyID = ConfigurationManager.AppSettings["companyID"];
string accessToken = "??????";
string accessSecret = "?????";
OAuthRequestValidator oauthValidator = new OAuthRequestValidator(accessToken, accessSecret, consumerKey, consumerSecret);
ServiceContext context = new ServiceContext(appToken, companyID, IntuitServicesType.QBO, oauthValidator);
DataService service = new DataService(context);
Customer customer = new Customer();
//just a test example. without missing tokens, i don't get here.
customer.GivenName = "Mary";
customer.Title = "Ms.";
customer.MiddleName = "Jayne";
customer.FamilyName = "Cooper";
Customer resultCustomer = service.Add(customer) as Customer;
//complete transaction
//catch {rollback transaction}
There is no automated way to get access tokens and secret from your application.
You need to generate them for the first time using user interaction(C2QB- Connect to Quickbooks) and then save them for future use. These tokens are valid for a period of 6 months after which you will have to call Reconnect api to renew the tokens or do a C2QB interaction again to get new tokens.
https://developer.intuit.com/docs/0025_quickbooksapi/0010_getting_started/0030_integrate_your_app/disconnecting_from_quickbooks/0050_how_to_reconnect