I want to have a Logic App that gets per tenant all its subscriptions.
I understand that there is a rest API for that purpose:
GET https://management.azure.com/subscriptions?api-version=2020-01-01
as mentioned in the Subscriptions - List documentation.
Two questions:
Where do I specify here for which tenant I want to get the list of subscriptions?
I understand that I need a token in order to get this data, but how do I get this token and from where exactly?
As it states in the documentation you linked to, the API call uses the Azure Active Directory OAuth2 Flow. This means it will get the subscriptions from the logged in user's tenant.
However, there's a Logic App connector to connect to Azure Resource Manager. And that connector has an action called List subscriptions.
When you add it, you create a service connection to Azure by logging in, which can be used for subsequent requests.
This sample implementation does the trick: it gets the subscriptions and returns them from the Logic App.
Related
We aim to collect data from the Azure Management APIs. These APIs provide information on the resources we have running in Azure, the consumed budget, etc (example). Following our design choices, we prefer to exclusively use Azure Data Factory to make the HTTP requests and store the data into our data lakes. This is fairly obvious, using the REST linked service. However, we struggle to correctly set up the OAuth2 authentication dance with this method.
Our first idea was to store the token and the refresh token within the Azure Key Vault. A series of HTTP requests within the pipeline would then test whether the token is still valid or otherwise use the refresh token to get a new token. The downside to this approach is that the token within the Azure Key Vault is never updated, when needed, and that the logic becomes more complex.
Alternatively, we were trying to set up the authorization through combination of a registered app and service principal to our Azure AD account. The REST linked service within Data Factory can be created with a service principal, which would then handle most of the information of the scope and consent. The service principal is also accompanied with a Azure app, which would hold the token etc. Unfortunately, we are unable to make this setup function correctly.
Questions we have:
Can we actually use a service principal / app to store our OAuth2 tokens? If so, will these be automatically refreshed within our app?
How do we assign the correct privileges / authorizations to our app that it can use this (external) API?
Is the additional logic with HTTP calls within Azure Data Factory pipeline needed to update the tokens or can these apps / service principals handle this?
Thank you for your time and help!
It is not a good idea to store the tokens in the keyvault, because they will expire.
In your case, two options for you to use.
Use service principal to auth
Use managed identity to auth(best practice)
Steps to use service principal to auth:
1.Register an application with Azure AD and create a service principal.
2.Get values for signing in and create a new application secret.
3.To call the Azure REST API e.g. Resources - List you mentioned, your service principal needs the RBAC role in your subscription.
Navigate to the Azure portal -> Subscription -> add your service principal as a Contributor/Owner role in the subscription like below.
4.In the linked service, configure it like below, fix them with the values got from step 2.
Don't forget to replace the {subscriptionId} in the Base URL.
https://management.azure.com/subscriptions/{subscriptionId}/resources?api-version=2020-06-01
5.Test the linked service with a copy activity, it works fine.
Steps to use managed identity to auth:
1.Make sure your data factory has enabled the MSI(managed identity), if you create it in the portal or powershell, MSI will be enabled automatically, don't worry about that.
2.Navigate to the Subsctiption in the portal, add the role to the MSI like step 3 in Steps to use service principal to auth, just search for your ADF name in the bar, the MSI is essentially a service principal with the same name of your ADF, which is managed by azure.
3.Then in the linked service, just change it like below.
At last, answer your questions.
Can we actually use a service principal / app to store our OAuth2 tokens? If so, will these be automatically refreshed within our app?
As I mentioned, it is not a good idea, just use the service principal/MSI to auth like the steps above.
How do we assign the correct privileges / authorizations to our app that it can use this (external) API?
To use the Azure REST API, just assign the RBAC roles like above, specify the correct AAD resource e.g. https://management.azure.com in this case.
Is the additional logic with HTTP calls within Azure Data Factory pipeline needed to update the tokens or can these apps / service principals handle this?
No need to do other steps, when you use the configuration above, essentially it will use the client credential flow to get the token in the background for you automatically, then use the token to call the API.
Here is a scenario. I have a SaaS product that needs to make api calls to customer's Azure cloud account. I understand a service principal can be created on the customer's AZ account, and if I have the credentials(app id, password, etc), I can make calls using that user/principal based on the permissions to that principal. One way is that customer creates it for my product, then comes to my product portal(web ui) and punches in this information which my SaaS product can then store securely in vault and use it.
Is there a better way to achieve the creation of the principal? For example via application manifest or something and then also be able to get a Event grid notification or something with the app/principal's creds to a webhook url endpoint?
Basically, I want this to be as automated as possible but cannot think of a way if it is even possible.
Normally if you are writing a multi-tenant application, you will set up your app registration as multi-tenant, and you will call the "common" endpoint for all users to log in.
when the admin from a different tenant logs into your application, if set up properly, a consent window will appear and when they consent, the Service principal will automatically be created in their tenant.
please see here: https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-convert-app-to-be-multi-tenant#understand-user-and-admin-consent
I am trying to query with an app ID all the resources a user has. My current implementation is to get all the resources my app has access to, and then query the RBAC of each one of those resources to see if the user has access. It seems to be way too many calls for something it can be done for my current user using Azure Resource Graph. Is there a way to use Azure Resource Graph but specify which user I want to get the resources for (assuming my app has reader access to all resources in the tenant)?
From your description, want you need to find is the role assignments in your subscription, its resource type is Microsoft.Authorization/roleAssignments, which is not included in the Azure Resource Graph.
Your option is to use the REST API - Role Assignments - List, filter with the ObjectId of the user in Azure AD. To get the access token to call the REST API with the AD App(the AppId you mentioned), you need to use the client credential flow, refer to this link.
Sample:
Check the scope in the response, they are the resources the user can access.
GET https://management.azure.com/subscriptions/<subscription-id>/providers/Microsoft.Authorization/roleAssignments?$filter=principalId eq '<object-id>'&api-version=2018-09-01-preview
I am developing an application that integrates with other business' Azure accounts. My application needs read access to the Azure Monitor service in our customers' Azure accounts. What is the best way to authenticate?
After reading, here's the current solution I came up with:
Have a customer create an App registration in their account. After creating the app registration, they assign the Monitoring Reader role to the application they created. The customer then will navigate back to the App registration and create a Client Secret. The customer then provides my service the client ID, tenant ID, and a Client Secret. My service will use those to authenticate with Azure and call Azure Monitor.
Is this the recommended way to authenticate with Azure as a 3rd party?
I am not sure if it the best way, but indeed it is a feasible way. This way named client credentials flow, you need to use this way to request the access token, then use the token to call azure rest api, e.g. Alert Rules - Get.
When you request the token, you need to specify the resource with https://management.azure.com/, also, you should note v1.0 endpoint is different with v2.0, v2.0 uses scope not resource, for difference details see this link. So you should choose the correct one depends on which version app your customer created.
Besides, correct some of your understanding of azure ad tenant and azure subscription. They are not called Azure account, the Azure monitor is a service in the subscription, the subscription locates in the tenant. The AD app(app registration) also locates in the tenant. You can understand the AD app is higher than the subscription, it is not in the subscription.
We have lot of references in the web to fetch the all AAD users but i need to fetch all the users from an Azure subscription.
I have created an App in Azure active directory and added that App to the Subscription then used ClinetId and Client secret to create the AuthToken. Used the created auth token to hit the below REST API(an Azure resource management REST API)
https://management.azure.com/subscriptions/{my subscription id}/resourceGroups/{My resource group name}/providers/Microsoft.ApiManagement/service/{my Azure managment API Name}/users?api-version=2018-01-01
But this rest API is retrieving only one User, which is mine.
Here i want to retrieve all the users in a subscription.
Here is the MSDN url i used as reference.
Please can any one help me on this.
It is not because of the free sub.
Does your app have the permission to the Graph API (to read users)? If you try the same user via PS console and you get the same output then its not your code but permissions (Good read on PS https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-powershell-1.0/ff730967(v=technet.10) ).
On the graph api here https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-graph-api-quickstart
You can find the answer for this question in below thread.
Removing the user from Azure subscription programtically(C#)