Azure Management API access from a web app - azure

Is it possible to gain access to the Azure Management APIs through the client ID and secret for a web app?
I have a web app through which i want to be able to manage Azure. I want to do this using the credentials of the application itself so that the current user does not have to be an azure administrator.
I have given the web app the necessary role on my subscriptions and obtained the access token through the client credentials grant flow in AD but i still get an unauthorized.
This is probably because the azure management API has no permission set other than delegated - the access works fine if i use the authorization code grant flow for the logged in user, but thats not what i want.
So to reiterate, if, given a web app that has RBAC to a subscription and is able to obtain an access token from AD, is there any way, without an interactive user, that the web app is able to use the management API??

Yes, you can obtain a token from AAD for a service principal and use that to manage resources as long as that service principal has all the access you need.
Make sure the token you get has a resource/audience of "https://management.azure.com" and is for the tenantId that the subscription is associated with.

You can also see this article from Brady Gaster that explains how to use Azure AD applications to manage Azure Services from an external app : http://www.bradygaster.com/post/using-windows-azure-active-directory-to-authenticate-the-management-libraries
EDIT : Azure AD supports Service to Service calls using OAuth 2.0 client credentials: https://msdn.microsoft.com/en-us/library/azure/dn645543.aspx
Hope this helps,
Julien

Related

Give user permession with Azure AD

I have an already deployed application on azure app service which uses azure AD for authentication and authorization.
Unfortunately the developer who worked on it is no longer available
i got access to all Azure resources and source code but i cant figure out how can i add my azure account as one of the users to the app (i can login but its an empty view for me unlike what it used to be with the developer access).
Also i find the app registered on Azure AD and i am an owner there but still with no right access.
When i try to login localy from the frontend it say
Selected user account does not exist in tenant 'Default Directory' and
cannot access the application '[some numbers] in that tenant. The
account needs to be added as an external user in the tenant first. Please use a
different account.
Would appreciate any help and many thanks in advance.
I can login but it’s an empty view for me unlike what it used to be
with the developer access
This is because your backend application is enabled with Azure AD Authentication.
After you sign in to your front-end application, you still can't access the data from the back-end app, because the back-end app now requires Azure Active Directory sign-in from the front-end app
To access the application, follow the below steps:
Grant the front-end access to the back end
Configure App Service to return a usable token
Use the token in your code
You can refer Enable authentication and authorization for front-end app in Authenticate users E2E - Azure App Service | Microsoft Docs for the detailed steps

Is it possible to call external Azure Service with AD Token from within D365/PowerApp plugins?

I am new to D365/PowerApps and wonder if i have a Azure Service, (Azure Functions or WebAPP) that is secured with Azure AD tokens (App Registrations).
Can I get an Access Token to my external services using Azure AD from within a plugin step in d365? How do I get such token on behalf of the context the plugin when running as a user.
You'll need to use Flow and compose a http request to get the token:
https://flow.microsoft.com/en-us/galleries/public/templates/edfa8fde25644f149448c8d8cff44699/call-a-web-service-from-a-powerapp/
Here's a good explanation on how to do it using the REST API:
https://stackoverflow.com/a/36982924/1384539
If I understand your question correct,
You have an Azure function APP or external azure service and that is secured by creating Azure AD App with it's roles delegation and so on.
Now you need Access token for this Azure APP with client ID and Client Secret.
We had this similar thing in Dynamics 365 i.e When we wish to use Dynamics 365 Webapi, We need to create Azure AD App and then provide roles delegation so that this app will have access to Dynamics 365.
In Plugin we can give details with client Id and Secret and then generate Token which will be used for Furthure process during plugin Execution.
Note: Most of these plugins we run under System context.
Here are few examples which will lead you to your desired direction.
Most of the Examples also talk about creating Non-Interactive user in Dynamics but in your case that shall not be needed because you are not communicating with Dynamics via (Azure AD App) rather you communicate with Azure functions or so on.
Link 1
Link 2
Link 3

How do I use the azure msal library to access azure service management apis?

All of the examples on the microsoft azure site having to do with a client application or a service principal having access to azure apis all show the graph apis as the example.
I got those to work, but what I need to do is access the azure service management apis.
If I take an auth token that works for the graph api and use it for the service management api, I get an "Authentication failed." error.
I have added the api permission for "azure service management" and the user_impersonation delegated permission type to my public client app, but the management apis still fail.
Am I going about this all wrong?
I get the idea that the service management apis are authenticated a different way since there's absolutely no mention of using them anywhere in any of the auth examples.
I suppose you are using the client application or a service principal to access azure resources. If so, you are using the client credential flow, but the user_impersonation of Azure Service Management API is a delegated permission, it will not take effect in this flow.
The permission is used to be consent by the user who login to the AD App e.g. in the auth code flow, when it has been consent by the user, the App will be able to represent the user to access the azure resources, note the permission is from the user, not the app. So if you want to use this flow, the user should have a role in the subscription or specific resources.
To access the azure resources with the client application or a service principal, you just need to add the service principal as an RBAC role in the Access control (IAM) of your subscription or specific resource, no need to add any API permission in Azure AD, see this link. Then the service principal will be able to access the azure resources.
When you getting the token to access the azure resources, e.g. call the REST APIs, the scope should be https://management.azure.com/.default, not the https://graph.microsoft.com/.default, you can just get the token for one resource in one time.

Credentials prompt for access to Azure management APIs

I've been using the Azure fluent management APIs (https://github.com/Azure/azure-libraries-for-net) with some success in .NET Core.
However, I want to prompt the user to enter some credentials for a Microsoft account. Those credentials would have access to one or more Azure tenants / subscriptions, so I'd like to be able to use the result to browse and manage resources there.
This is something very close to what I would believe Azure Data Studio does: you can enter some Azure creds, and your resources will appear in the app.
I'm trying to understand the best approach for this. There seem to be a billion sites out there when you talk about Azure AD app registrations, but I haven't found a fruitful specific search query yet. I know I can register an app, get a client ID and client secret. I know I can set it to be usable by organisational accounts in the current tenant, or all tenants.
I can add the "Azure Service Management (delegated permissions : user_impersonation)" permission to my API permissions section for the app, but what's next?
If I use Microsoft.Identity.Client (as in https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-netcore-daemon), I run into some questions:
AcquireTokenForClientAsync doesn't prompt the user - I guess because it's getting a token for the app to act with its own permissions?
AcquireTokenOnBehalfOfAsync wants a JWT.. great! I'll pass the one I got from AcquireTokenForClientAsync! Nope, AADSTS70002: Error validating credentials. AADSTS500137: The token issuer doesn't match the api version: A version 1 token cannot be used with the v2 endpoint.
I don't know what scope I want. https://management.azure.com/user_impersonation is apparently invalid.. https://management.azure.com/.default works, but is that right? It's a guess, combo of the former and a .default suffix I found for Graph API scopes online. Any docs on this?
I ultimately get a JWT and tenant ID back. I can't find a way to use a JWT with the Fluent management APIs.. and my account (for instance) is associated with 3 tenants or 5 different tenants / directories - so how do I choose?
That's just what I've tried, the appropriate route might be a different one. In summary: I want a .NET Core Console app to request user credentials, and then get access to the Azure resources they have access to, in order to perform some resource management.
AcquireTokenForClientAsync doesn't prompt the user - I guess because it's getting a token for the app to act with its own permissions?
You are using the OAuth 2.0 client credentials grant to access web-hosted resources by using the identity of an application. This type of grant commonly is used for server-to-server interactions that must run in the background, without immediate interaction with a user .
AADSTS70002: Error validating credentials. AADSTS500137: The token issuer doesn't match the api version: A version 1 token cannot be used with the v2 endpoint.
Azure AD provide two service : Azure AD V1.0 and Azure AD V2.0 . Please refer to Comparing the Azure AD v2.0 endpoint with the v1.0 endpoint . You can't use v1 token to acquire v2's token in a on-behalf-of flow .
AcquireTokenOnBehalfOfAsync wants a JWT.. great! I'll pass the one I got from AcquireTokenForClientAsync
AS pointed above , That function is used to acquire an access token for this application (usually a Web API) from the authority configured in the application, in order to access another downstream protected Web API on behalf of a user using the OAuth 2.0 On-Behalf-Of flow. So you can't use app token which acquire using Client Credential flow .
https://management.azure.com/.default works, but is that right? It's a guess, combo of the former and a .default suffix I found for Graph API scopes online. Any docs on this?
You are using the Azure Active Directory v2.0 and the OAuth 2.0 client credentials flow , when sending a POST request to the /token v2.0 endpoint ,the scope should be :
The value passed for the scope parameter in this request should be the resource identifier (Application ID URI) of the resource you want, affixed with the .default suffix. For the Microsoft Graph example, the value is https://graph.microsoft.com/.default. This value informs the v2.0 endpoint that of all the direct application permissions you have configured for your app, it should issue a token for the ones associated with the resource you want to use.
Please check the Get a tokensection in above document .
I ultimately get a JWT and tenant ID back. I can't find a way to use a JWT with the Fluent management APIs..
AFAIK , currently Azure AD V2.0 apps can use:
Its own API
Microsoft Outlook APIs
Microsoft Graph API
Azure AD V2.0 currently doesn't support Azure management APIs .
So you problem is you need to allows work and school accounts from Azure AD and personal Microsoft accounts (MSA) which works with Azure AD V2.0 , but you can't use Azure management APIs . You can use Azure management APIs in Azure AD V1.0 but it allows only work and school accounts to sign in to your application , unless you invite Microsoft accounts as guest user in Azure AD V1.0 ,but you need to configure to point to the tenant-specific endpoint :https://login.microsoftonline.com/{TenantId_or_Name}). during authentication if you want to login with MSA in v1.0 apps.
Update:
You can use Code flow and azure ad v1.0 endpoint , user will be redirect to AAD's login page and enter their credential. Here is code sample for .net Core .
With Azure AD V1.0 endpoint , requests are sent to an endpoint that multiplexes across all Azure AD tenants: https://login.microsoftonline.com/common . When Azure AD receives a request on the /common endpoint, it signs the user in and, as a consequence, discovers which tenant the user is from. See document here . But in this scenerio ,you can only use work and school accounts(AAD) account to login .
The code sample in your link is using Azure Service Principal for Authentication , no interactive user login . You can use OpenID Connect Owin Middleware for authentication in .net Core applications as shown here .

How to configure consenting for an Azure app (AADSTS65005 error)

We have an Azure resource app whose APIs we want to expose for access by a client app on Azure. The two apps are on different tenants. The users accessing the APIs (Office 365 account holders) are on different tenants.
The whole set up works when we manually provision a service principal on the tenant that is trying to authenticate from the client app against the resource app. By that I mean they are able to log in using their Office 365 account and are shown the consent screen.
If we do not provision a service principal on the AAD tenant of the user trying to authenticate, we get this error:
AADSTS65005 - The app needs access to a service <service> that your
organization org.onmicrosoft.com has not subscribed to or enabled. Contact
your IT Admin to review the configuration of your service subscriptions.
It is not feasible for us to provision a service principal on every tenant that is accessing our app (resource app). Is there something we are missing? Are we using the right flow?
You can find help for your scenario here: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-devhowto-multi-tenant-overview#understanding-user-and-admin-consent. (Scroll down to Multiple tiers in multiple tenants)
In the case of an API built by an
organization other than Microsoft, the developer of the API needs to
provide a way for their customers to consent the application into
their customers' tenants.
The recommended design is for the 3rd party
developer to build the API such that it can also function as a web
client to implement sign-up:
Follow the earlier sections to ensure
the API implements the multi-tenant application registration/code
requirements
In addition to exposing the API's scopes/roles, ensure
the registration includes the "Sign in and read user profile" Azure AD
permission (provided by default)
Implement a sign-in/sign-up page in
the web client, following the admin consent guidance discussed earlier
Once the user consents to the application, the service principal and
consent delegation links are created in their tenant, and the native
application can get tokens for the API
Basically, all of the parts that your app needs must be present as service principals in the customer's tenant. This is a requirement of AAD.
The only way for that to happen is for an admin to go through consent for the API and app separately, since they are registered in different tenants.
If they were registered in the same tenant, you could use the knownClientApplications property in the manifest to allow consenting to both at the same time.
In my case, I am exposing my own API and trying to access this API from my other Application (Client Credentials mode), I removed the default permission on both of the app(consuming app and api app) - "Azure Active Directory Graph-> User. Read" since I thought I don't need that but that caused this problem "The app needs access to a service .... that your organization has not subscribed to or enabled. Contact your IT Admin to review the configuration of your service+subscriptions.
I got the clue from the answer of #juunas - point 2. Thx Juunas

Resources