Microsoft-authentication-library-for-dotnet: [Feature request ] OBO for service principals (was Getting error code 7000114 Application '{appIdentifier}' is not allowed to make application on-behalf-of calls)

Created on 22 Oct 2020  路  9Comments  路  Source: AzureAD/microsoft-authentication-library-for-dotnet

Which Version of MSAL are you using ?
MSAL 4.21

Platform
netcore

What authentication flow has the issue?

  • Desktop / Mobile

    • [ ] Interactive

    • [ ] Integrated Windows Auth

    • [ ] Username Password

    • [ ] Device code flow (browserless)

    • [x] Client Credential Flow

  • Web App

    • [ ] Authorization code

    • [ ] OBO

  • Web API

    • [x] OBO

Description:

I have a daemon app that authenticates to Azure AD to call web api. This is achieved with Client Credential flow. Daemon app gets a JWT to call the Web API. The web api needs to call another Azure Service - Data Lake. I want to use OBO Flow inside Web API, and it fails.

Really trying to use this: https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow
But the initial call to the middle tier is not done by the user, it is done by the Daemon app using Client credentials flow.

Expected behavior
JWT Token is returned.

Actual behavior
Error is returned:

{
"error": "unauthorized_client",
"error_description": "AADSTS7000114: Application '{appid}' is not allowed to make application on-behalf-of calls.\r\nTrace ID: edd4d517-bfc9-4363-bfc2-84539c296d00\r\nCorrelation ID: 07321853-3ad1-4a0f-aac4-1755fe184cd7\r\nTimestamp: 2020-10-22 10:03:57Z",
"error_codes": [
7000114
],
"timestamp": "2020-10-22 10:03:57Z",
"trace_id": "edd4d517-bfc9-4363-bfc2-84539c296d00",
"correlation_id": "07321853-3ad1-4a0f-aac4-1755fe184cd7",
"error_uri": "https://login.microsoftonline.com/error?code=7000114"
}

What kind of configuration is required on Azure AD to make this scenario work?

documentation question service-enhancement

Most helpful comment

@bgavrilMS client-to-app token meaning the users is requesting access not a daemon? Tbh, what difference does it make? Both a user and app (Azure AD app registration) are registered in AD, so why it would work for a "human" user but not the app? Both are valid identities.

The daemon app that wants to talk to the Web API has certain permissions in the data lake (using ACL). The daemon app has clientId and client secret, but the Web API doesnt have these credentials right? I dont want to expose these credentials to the Web API. The main reason is that I have 8 daemon apps connecting to the lake, each with different permissions. That is why I wanted the daemon identity to flow into web api.

Would there be any valid explanation why this would work for "human" users but not "background apps"?

All 9 comments

As far as I know, MSAL does not support OBO for app-to-app tokens, only client-to-app tokens. I am not sure if AAD even allows this.

Why can't you just get a token directly for Data Lake?

CC @jmprieur who's been looking at this scenario.

No AAD doesn't support it for 3P apps.

@bgavrilMS client-to-app token meaning the users is requesting access not a daemon? Tbh, what difference does it make? Both a user and app (Azure AD app registration) are registered in AD, so why it would work for a "human" user but not the app? Both are valid identities.

The daemon app that wants to talk to the Web API has certain permissions in the data lake (using ACL). The daemon app has clientId and client secret, but the Web API doesnt have these credentials right? I dont want to expose these credentials to the Web API. The main reason is that I have 8 daemon apps connecting to the lake, each with different permissions. That is why I wanted the daemon identity to flow into web api.

Would there be any valid explanation why this would work for "human" users but not "background apps"?

And correct this is not really MSAL bug, when I do OAuth2 HTTP Post to Azure AD it also doesnt work. Im just looking for some assistance here. The documentation doesnt mention for what type of client auth flow OBO works.

cc: @hspin and @yordan-msft for the scenario.

@hpsin FYI

Thanks @jmprieur . This is something we're reasoning over. The hard part here is that it means something slightly different to everyone, so I really appreciate laying out the expectations in your request @ErikMogensen .

What I'm seeing is that SP A calls SP B, then SP B OBOs the token to call SP C.

The token in the second leg would look like:

oid: A
sub: A
appid: B // This is the app making the call
roles: Roles of A on C
scp: Delegated permissions of B on C // Namely, this is what (of the roles A has) B is allowed to do on behalf of A
original_appid: A

Is that about what you'd expect, and would it satisfy your requirements?

In this scenario, with DataLake as C, DataLake would have to update to understand what the scopes mean, since role-only checks would grant B too much permission. At the same time, B is not intended to call C directly - it would not have any roles, possibly, is that right @pwlodek?

Was this page helpful?
0 / 5 - 0 ratings