Supporting the On-Behalf-of flow with managed service identities - azure

A very common flow for applications running in Azure and App Services is the on-behalf-of flow where the app can exchange an incoming access token along with its ClientId/ClientSecret to get access to another resource as the user. Looking at the current, limited, docs on the MSI API, I only see getting an access token as the app itself.
How/when will the OBO scenario be supported?
I am aware that you could store the ClientId/ClientSecret in Key Vault and then use the MSI creds to retrieve those, but that seems redundant.

MSI does not support the On Behalf Of flow yet, or other delegated confidential client OAuth 2.0 flows with Azure AD (like the auth code flow). It is in the design process, no ETA announced yet.

Related

Can we use client credentials flow on regular Azure users?

We would like to use Azure client credentials flow to do authentication for our service accounts. The thing is our service accounts are just regular users in Azure AD. They are not registered apps. The way our company sets up Azure makes it very heavy to register apps, so we would like to avoid it. So the question is, can we use client credentials flow for regular users in Azure? We need this as in our CI/CD we cannot popup a browser and let users do device-based authentication. We need the user to be able to authenticate in an automated way.
You can't use client credentials flow where an Azure AD user is involved in the authentication flow.
Micrsofot Documentation - client credentials flow
This type of grant is commonly used for server-to-server interactions that must run in the background, without immediate interaction with a user.
But you can use one of the following supported authentication flow where a user is involved;
Micrsofot Documentation - authorization code flow
Micrsofot Documentation - implicit grant flow
Micrsofot Documentation - device authorization grant flow
Device authorization grant flow might work in your case?

Is there an OAuth flow that doesn't require a client_id?

I have created a Microsoft Teams bot built using a Golang port of the Bot Framework. It is a multi tenant bot which lives in my infrastructure.
It is easy to add the bot as a "Teams Application" by selecting it from the marketplace (for free), however, to function correctly it needs additional Microsoft Graph permissions. Specifically read the title of a MS Teams Channel / Group Chat.
This seems to be a challenge for users as almost no one - even those 'in IT' seem able to correctly add the permissions required, even with documentation.
I've been helping them personally but it's not a commercial product so not viable in the long term.
I would like to find an OAuth2 flow which would allow a privileged user to authenticate with their Azure tentant and grant the necessary privileges for my application to do it's thing. Or, alternatively create the client registration in advance of installing the bot.
Every OAuth2 flow requires me to have (or know) my client_id before making the request. Given it's in the users Tenant, I don't have access to it; the users can authenticate against their Azure AD tenant though, so they must receive a bearer token which would allow them access to create or update permissions on an Azure Application.
There is chance to use the OAuth 2.0 client credentials. This grant is specified in RFC 6749. This grant is to access the web hosted resources. This resource will directly identify the application based on the identity of the application. In server-to-server communication we can use OAuth 2.0. This can be referred as "Service accounts" or "Daemons".
Microsoft identity platform and the OAuth 2.0 client credentials flow

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 get Azure AD token in web app silently C#

i need to get Azure token in my app (C#) to perform Graph API operations on users, but without sign in all the time when app invoked (app must be full automate, working in timer job) so i have a question how to made process of token acquiring fully automate (without user)?
All that I found about this topic:
Get access without a user
But I failed to recreate it.
The OAuth2 flow you are describing is called the "Client Credentials Grant" and is in detail described here.
In short it is relevant in this case and works like this:
First, user interaction is not possible with a daemon application,
which requires the application to have its own identity. An example of
a daemon application is a batch job, or an operating system service
running in the background. This type of application requests an access
token by using its application identity and presenting its Application
ID, credential (password or certificate), and application ID URI to
Azure AD. After successful authentication, the daemon receives an
access token from Azure AD, which is then used to call the web API.
Have a look at this implementation to see how it is done in code.
Using OAuth On-Behalf-Of works exactly what you describe. Which On-Behalf-Of method, there is no user interaction to obtain the user's consent to access to the downstream API (e.g. Graph API). In other words, the user identity & permission is silently delegated in a full request chain. In a real-world corporate environment, your app would be normally authenticated by another identity provider (e.g. Active Directory) not Azure AD, which after then requests authorization to Azure AD OAuth endpoint.
When requesting access token, you must set its type is requested_token_use=on_behalf_of
Here is reference to POST to the endpoint https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-on-behalf-of
Here is the reference of SSO authentication with OAuth On-Behalf-Of https://learn.microsoft.com/en-us/outlook/add-ins/authenticate-a-user-with-an-sso-token

Using Azure ACS to get access to underlying identity provider's access/refresh token

I couldn't find any clear indication of whether ACS provided this functionality or not.
I would like to leverage ACS to do most of my authentication work, but I would also like access to the identity provider's access/refresh token that was sent to ACS. I can then make API calls to the identity provider to access the user's data such as calendar or profile information (assuming I've requested this access during the application authorization steps).
Is this possible using ACS? It seems as if ACS abstracts most of the underlying identity provider information out, and only provides an ACS token used purely for authentication purposes, not for use in talking directly to the identity provider.
Yes and no :)
ACS does support this feature for the providers that do support that. It is not explicitly documented, because it is not special. ACS does not "just create own token for pure authentication purposes".
If you take the FaceBook IdP, ACS does provide you the FaceBook token, which you can use to query the FaceBook Graph API. And what permissions for the API you will get, depends on what permissions your FaceBook Application will require from authenticating user. I am not sure about the level of sophistication of FaceBook consent framework, but the last I plaid with it, the authenticating user could only Accept all required consents, or reject all. He was not able to selectively chose which consents to grant to your application, out of all requested.
Having said that, from Google Authentication Provider, you do not receive additional tokens. At least with the old OpenID 2.0 imeplementation. Now with the deprication of OpenID 2.0 and moving Google to OpenID Connect, there is a requirement that you explicitly register your ACS Namespace as application with Google. At that point, I assume (speculation of mine) you may declare requested consents, just as you do with FaceBook. And if Google sends the token, you will definitely receive it in your application through the ACS.
ACS is super powerful service that will not die. As in the referenced blog post, all of its features will sooner or later be moved to Azure AD itself. And a migration plan will be provided (hopefully :) ).
But also, note that ACS do only talk with Yahoo, Google, Facebook, Azure AD and any WS-Federation IdP. And WS-Federation protocol is not known for being very flexible and giving you the flexibility you want. ACS in theory also supports OAuth 2.0, but its support does not include Federation, only local identity management (identities local to ACS self).
Also, note, that ACS is being used by a lot of Microsoft owned services, like Visual Studio Online, Azure Service Bus and others. ACS is neither dead, nor will just die letting all its customers on the wild.
You can decide to use it today. Or you can decide to use whatever features are today available in the Azure AD itself. Or wait until ACS is fully migrated to Azure AD.

Resources