Assign Azure CSP subscriptions to your customers programmatically - azure

I have created an AZURE CSP subscription for a customer. When I log in to the particular customer directory as a partner admin user (Customers -> Click the dropdown for a customer -> Microsoft Azure Management Portal link), I am able to see the subscription. But when I try to login as the admin of the customer domain/directory, I am not able to see it.
When I searched about it, I came across the link
https://learn.microsoft.com/en-us/partner-center/assign-azure-subscriptions
Is there any way to do the step Assign Azure subscriptions to your customers through API.

You could use Azure Rest API Role Assignments - Create or Role Assignments - Create By Id.
You can see that there is a Try It feature in the page but we cannot make it work with an CSP admin, because if we sign in with an CSP admin, the access token will be issued for the CSP admin's tenant rather than customer's tenant by default.
To call Azure rest API, you need an access token for Azure. Please refer to this document.
Here is my sample for your reference:
Get the access token for Azure service in Postman. Sign in with your CSP admin to generate the access token. Remember that you should put the customer's tenant id in Auth URL: https://login.microsoftonline.com/{custopmer's tenant id}/oauth2/v2.0/authorize and Access Token URL: https://login.microsoftonline.com/{custopmer's tenant id}/oauth2/v2.0/token
Use this access token to assign Azure subscription using Role Assignments - Create.

Related

Azure API Management Prevent Subscription Key Visibility for Admins

Is it possible to prevent subscription keys being visible to APIM admins? I want them to only be visible to the developer in question via the developer portal.
I have admin access to an APIM instance. I have access to the subscription keys of all of the user accounts by toggling the Show/hide keys option for any particular record. I don't want this to be the case, I would like it to be a secret they generate for themselves that no one else can see.
Is this possible at all? If not is there a similar alternative?
Firstly, created the 2 users in Azure and given access to only APIM Resource as APIM Service Contributor.
Created the 2 Subscriptions in the APIM by logging to the APIM resource using both of the user's credentials in Azure and given owner access to opposite user.
Using these subscription keys, we can secure the APIs published to the APIM Resource where we can prevent the users to access our APIs data using those keys, so Admin consent is required to approve the subscription keys request for the users.
I believe, it is not possible to restrict the admins from visibility of Subscription keys in APIM.

Can I get a list of B2C Tenant Users (Created using signin-signup policy) Using Graph Explorer?

I'd like to use Microsoft Graph Explorer to work with my Azure AD B2C Tenant.
Initially, all I want to do is retrieve a Custom Attribute that I've assigned to an application registration. The custom attribute will store the UserAppPermission value, a 'role' replacement for B2C since it doesn't natively support them.
Can I get a second set of eyes on my process? I'd like to make sure I'm reading this properly.
First goal: Get a list of applications registered to my B2C Tenant. Reasoning is... if the app registration doesn't appear then future queries are unlikely to be successful.
Resource#1 "Manage Azure AD B2C with Microsoft Graph" (Note B2C in the title)
(1) I registered an application in my B2C tenant with permissions in excess of the minimum, checked this process twice: Register a Microsoft Graph application (Note B2C in the opening paragraph, and throughout the document).
(1a) Uncertain if the Azure portal was being buggy, I also registered this application with the 'Global Administrator Role' ... absolute overkill & insecure ..
(1b) I am certain that I assigned the appropriate Microsoft Graph API permissions in the app registration tab
(1c) As described in the doc, I also granted the application the user administrator role, although that is contained within the global administrator role.
(1d) Per the doc, "Now that you've registered your management application and have granted it the required permissions, your applications and services (for example, Azure Pipelines) can use its credentials and permissions to interact with the Microsoft Graph API."
When I run "https://graph.microsoft.com/beta/applications" to get a list of registered applications, all I see is the single App Registration our 'root' Azure account has for our Azure Functions App. Since this was an article on managing azure ad B2C with Microsoft Graph, I was expecting to see the applications registered to my B2C Tenant.
? Does anyone read (1d) to mean that I should not be able to use https://developer.microsoft.com/en-us/graph/graph-explorer, logged in as the B2C global administrator, and granting all permissions the endpoint requires, to make Microsoft Graph API queries?
Next goal: Get a list of users registered to my B2C Tenant
Resource#2 "List Users" - the link to this resource was provided by Resource #1, link provided above.
(1) There only mention of B2C in this article is: "The $count and $search parameters are currently not available in Azure AD B2C tenants."
(2) The request to get all users is GET "https://graph.microsoft.com/v1.0/users"
(2a) The request returns a list of users for the MyOrg's root AD tenant, not the application's B2C tenant. Not surprising since there's nothing in the request to specify the B2C tenant.
(3) Another resource provides this request format: https://graph.microsoft.com/beta/.onmicrosoft.com/users, which specifies the b2c tenant.
(3a) This executes without error in Graph-Explorer but does not return any of the users that registered for the application using the sign-up/sign-in policy (Consumer B2C Users). It still returns a list of users for the 'root' Azure account.
Update re:specifying tenant in graph-explorer:
While logged in to Graph Explorer us my work MS email which is registered as a global admin for our Azure account and owner of the B2C tenant I specified:
This returns a list of applications for the root Azure account, not app registrations for the B2C Tenant I specified. Perhaps I misunderstood the intent of this Graph API call.
I optimistically ran 'https://graph.microsoft.com/beta/identity/b2cUserFlows' with the tenant specified in the URL (as in screenshot). Result:
"error": {
"code": "AADB2C",
"message": "'4fba2ea8-XXXX-XXXX-964e-99f48b79d925' is not an Azure AD B2C directory...
I'm still not certain what the UUID returned in the message represents. The UUID has no correlation, that I can find, with the tenant I specified in the URL.
The reason is that you are using an Azure account which is from your root AAD tenant.
You have two options to resolve it.
Specify the tenant in the Graph Explorer URL:
https://developer.microsoft.com/en-us/graph/graph-explorer?tenant={Your b2c tenant}.onmicrosoft.com. Still use that Azure account from root
AAD tenant to sign in and you can get a list of applications and
users of your B2C Tenant now.
Another method is creating a new user in your B2C tenant and assign
Global admin role to it. And then sign into
https://developer.microsoft.com/en-us/graph/graph-explorer with
this new user. Now you can list applications and users of your B2C
Tenant as well.
Update:
Don't use a Consumer account (local account) for the second suggestion. You should create an AAD user (work account, format: mytenantname.onmicrosoft.com ) in Azure portal in B2C tenant and assign it global admin role.
Overview of user accounts in Azure Active Directory B2C for your reference.
#AllenWu's second solution was, in effect, correct but not explicit enough for me.
The New user interface in the B2C Tenant offers three options for creating users: Create user, Invite user and Create Azure AD B2C user. Most of my work has revolved around B2C users so I did that and gave the user Global Admin rights and my Graph Explorer results were unchanged.
Another user provided this suggestion and made it clear that I needed to create a user w/an email address of #my-tenant-name.onmicrosoft.com. I created such a user, assigned it Global Admin rights, and I was able to use Graph Explorer as I expected.
Note that users with an email of "SomeTestUser_gmail.com**#EXT#**#my-tenant-name.onmicrosoft.com do not behave in the same way.
Thanks for the suggestions & feedback & I hope this helps if you ended up here with the same question.

Azure Resource Manager on behalf of Azure AD Multitenant App

General Overview of what I am trying to achieve
I am trying to build an Azure AD Multitenant Web application which allows me to manage resources in customer subscriptions/tenants using the Azure Resource Manager (ARM) APIs. I am pretty new to Azure AD Multitenancy.
The Ideal control flow
1. A customer browses the Applications (ideal an admin of the customer tenant)
2. Will be granted with Azure AD authorize flow
3. Accepts everything and grants admin consent for the AD App in their tenant
4. Unclear: The AD App will be granted contributer access on a subscription or resource
5. My Web App will be able to use the AD App credentials to manage the customer resources using the ARM APIs
Problem
Steps 1-3, 5: Are clear and I know how to build that.
Step 4: I am not sure how to build that so that step happens automatically.
Solutions I have considered
The worst case would be the customer AD Admin must manually grant the AD App access to a subscription or resource using the Azure Portal.
One idea that came to my mind is that you require the user_impersonation permission on Azure Service Management API.
After the user logs in, you could list out the subscriptions available, allowing the user to select one.
Then list out the resource groups if needed.
Once the user confirms a selection, your app could add itself as a Contributor on the targeted resource through the Management API, on behalf of the currently signed-in user.
To do this, you will need the object id of the service principal for your app created in the target tenant.
You can get it by acquiring an app-only token for e.g. the Azure Management API from that tenant's token endpoint after the user has logged in.
The token will contain an oid claim, which is the object id for the service principal.
Of course the user who signs in would have to have the ability to modify access to the target resource.
I would say the downside of this approach is that the organization must trust your app to only do the thing it claims to do.
The approach where they grant the access manually allows them to be in control fully.

How to acces AzureRM with a AzureAD Multi-Tenant App using personal Microsoft account?

My target is simple: use an Azure AD multi-tenant app to be able to call Azure Resource Manager API on other tenants. However, I cannot figure out how to do it when you sign in with a personal Microsoft account.
I created an Azure AD multi-tenant app using a company's tenant
Then created a test ASP.NET Core Web application which goes to a such URL:
The Microsoft's login page shows up and I'm able to log in successfully with a personal LIVE.COM, where the test Web app receives the callback with given redirect URL. I have another Azure tenant created with my personal MS account which I'm trying to access.
The Multi-Tenant AAD App gets added to the "personal space" at https://account.live.com/consent/Manage, but not to the Azure AD tenant.
It probably makes sense from the technical standpoint, but how do I add the AAD app to another tenant when logged in with a personal account?
I figured that the "authorize" URL must include the AAD tenant name/ID instead of "common" (confirm that a Service Principal gets created on the target tenant):
However, that tenant name/ID is unknown when a user logs in, and I don't really know what API to use to query it.
Should be done by hand - detecting a personal MS account and finding the association with AAD tenant, or is there an API that can facilitate this? In both cases, how? What if an account is associated with multiple tenants ("Switch Directory" in Azure Portal)?
P.S. using URLs https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize ("orgainzations" instead of "common") or https://login.microsoftonline.com/common/oauth2/authorize (without "v2.0") won't allow using a personal MS account to log in.
UPDATE
To demonstrate the problem, there are 4 tests were made to access resource "https://management.azure.com/" with a multi-tenant app:
Authorize Microsoft's "Microsoft Azure" app with v1 endpoint - it works with personal accounts:
https://login.microsoftonline.com/common/oauth2/authorize?client_id=1950a258-227b-4e31-a9cf-717495945fc2&response_type=code&response_mode=form_post&resource=https://management.azure.com/&nonce=123&state=common&redirect_uri=http%3A%2F%2Flocalhost%3A64696%2FAuthCallback
Authorize the same "Microsoft Azure" app with v2 endpoint - now it does not allow to use personal accounts:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=1950a258-227b-4e31-a9cf-717495945fc2&response_type=code&response_mode=form_post&scope=https://management.azure.com/.default&nonce=123&state=common&redirect_uri=http%3A%2F%2Flocalhost%3A64696%2FAuthCallback
Authorize a custom multitenant app against v1 endpoint (insert your client id) - shows error AADSTS50020 "User account 'user#live.com' from identity provider 'live.com' does not exist in tenant 'contoso.com' and cannot access the application ''(app name) in that tenant. The account needs to be added as an external user in the tenant first. Sign out and sign in again with a different Azure Active Directory user account."
https://login.microsoftonline.com/common/oauth2/authorize?client_id=&response_type=code&response_mode=form_post&resource=https://management.azure.com/&nonce=123&state=common&redirect_uri=http%3A%2F%2Flocalhost%3A64696%2FAuthCallback
Authorize a custom multitenant app against v2 endpoint - same as test #2 - does not allow personal accounts.
Thoughts.
The v2 endpoint does not allow personal accounts for the resource https://management.azure.com/, where the v1 endpoint does.
Microsoft Azure app probably has a manifest with undocumented or hardcoded settings that allows to use personal accounts for the desired resource.
ANSWER
Long story short, it's not possible for general public as per Microsoft.
Only V2.0 endpoint supports personal account(even it doesn't belong to any Azure AD tenants) to login.
It works with personal account when you use v1.0 endpoint.
That's because that personal account belongs to at least one Azure AD tenant. Then this personal account will be recognized as a guest user in the tenant.
The v2 endpoint does not allow personal accounts for the resource
https://management.azure.com/
Yes, if you login in with personal account when you use v2.0 endpoint, it will detect that you belong to personal account and will redirect you to the personal account login endpoint https://login.live.com/oauth20_authorize.srf.
You must identify the tenant to login in with personal account when use v2.0 endpoint
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=20244877-ae8f-4325-b4cf-c6dc239cb124
&response_type=code
&redirect_uri=https://localhost
&response_mode=fragment
&scope=https://management.azure.com/.default
&state=12345
&nonce=default
Then you can call https://management.azure.com/tenants?api-version=2016-06-01 to list all the tenants that account belongs to.
Update:
It is normal that you can't do that. You are not telling Azure AD that
the which tenant the MSA user is an external user, so Azure AD is
making a guess and checking in the tenant where the app is registered
(tenant A). If you expect external users to be able to sign in, you
must specify the tenant where the guest has previously been invited to
(e.g. tenant B).

Azure AD - Multi-Tenant with Daemon Service Authentication flow, what limits tenants from accessing other tenants users?

I have created a Service/Dameon application to handle the authentication process for Microsoft Graph SDK. I pretty much created a HttpWebRequest and created a URL which I passed in my application's secret and client_id which generated an access_token. This access_token was then used with the Microsoft Graph CSharp SDK to authenticate for OneDrive for Business.
I have successfully proofed this out for a single tenant and it is able to pull back all the user's OneDrive metadata on files and folder facets. My question is if I wanted to allow access for other tenants to this application, what users would they see?
If Tenant A creates an application that reads all the non-global admin accounts to pull back OneDrive for Business meta-data and Tenant B has its own list of non-global admin accounts where Tenant B wishes to read from - Where is the restrictions to limit Tenant B to only having access to their own list of non-global users.
The only thing I can think of is that Tenant B would need to create their own client_id and secret- is there another way of doing this?
The only thing I can think of is that Tenant B would need to create their own client_id and secret- is there another way of doing this?
Before the application could interact with Azure AD through OAuth 2.0 protocol, we need to create the corresponding service principal to the target tenant. When we register the application on the Azure portal, the portal already create the service principal for us in the developer's tenant.
And if we are developing an multi-tenant app, the users on the other tenant need to grant the permission. After users consent, a service principal is created in users' tenant.
So another way is, we need to provide a way to enable users in other tenant to able to consent. For example, we can use the authorization code grant flow. Here is an example for your reference( refer here):
// Line breaks for legibility only
https://login.microsoftonline.com/common/oauth2/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=query
&resource=https%3A%2F%2Fservice.contoso.com%2F
&state=12345
And after the service principal is created on users' tenant, we need to use the users's tenant to acquire the token like below
POST https://login.microsoftonline.com/{users' tenantId}/oauth2/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=<clientId>
&client_secret=<clientSecret>
&resource=<resource>
Here are some helpful documents for your reference:
Application and service principal objects in Azure Active Directory
How to sign in any Azure Active Directory (AD) user using the multi-tenant application pattern

Resources