I have an Azure AD service principal in one tenant ( OneTenant
) that I would like to give access to an application in another tenant ( OtherTenant
).
The service principal in tenant OneTenant
is a managed service identity for an Azure Logic App. So what I actually want is to call an API from my Logic App. This API is protected by an Azure AD application in OtherTenant
.
The application in OtherTenant
defines a number of roles and the service principal in OneTenant
should have one of these roles so it can call the API.
I tried the following:
OtherTenant
to multi-tenantran the following PS command to attempt to add the SP to a role in the app:
New-AzureADServiceAppRoleAssignment ` -ObjectId <object-id-of-sp-in-one-tenant> ` -Id <role-id> ` -PrincipalId <object-id-of-sp-in-one-tenant> ` -ResourceId <app-id-in-other-tenant>
(both logged in in OneTenant
and OtherTenant
)
This gives an error stating that either app-id-in-other-tenant
or object-id-of-sp-in-one-tenant
can not be found, depending on where I am signed in.
I also tried creating a Service Principal in OneTenant
based on the app-id from OtherTenant
In that case I get an error message: Authenticating principal does not have permission to instantiate multi-tenantapplications and there is not matching Applicationin the request tenant.
Taking the command as is from your question:
New-AzureADServiceAppRoleAssignment `
-ObjectId <object-id-of-sp-in-one-tenant> `
-Id <role-id> `
-PrincipalId <object-id-of-sp-in-one-tenant> `
-ResourceId <app-id-in-other-tenant>
Try changing the last parameter value ie ResourceId
Currently you're passing <app-id-in-other-tenant>
Replace that with <object-id-of-API-in-other-tenant>
Ok, I finally got around to testing if the solution presented by Rohit Saigal works. It does point in the right direction but is not complete.
First step is to create a service principal in OneTenant
that represents the application in OtherTenant
. So while signed in to OneTenant
, run the following script:
$spInOneTenant = New-AzureADServicePrincipal -AppId <app-id-in-other-tenant>
Next step is to run the New-AzureADServiceAppRoleAssignment
cmdlet with the following parameters:
New-AzureADServiceAppRoleAssignment `
-Id <role-id> `
-ObjectId <object-id-of-sp-in-one-tenant> `
-PrincipalId <object-id-of-sp-in-one-tenant> `
-ResourceId $spInOneTenant.ObjectId
The trick is to use the object id of the service principal you created in the previous step as the ResourceId
.
The question/answers presented here were helpful, but yet it took me some time to work through the details and actually make it work, so allow me to elaborate some more on the above, as it might help others too.
Two tenants:
Home Tenant
. Other Tenant
. One Azure App Service API app
, with access managed by the Home Tenant
.
One Logic app
placed in a subscription in Other Tenant
that need to securely access the API app
in the Home Tenant
.
For the API app
to delegate identity and access management to Azure AD an application
is registered in the home tenant
's Azure Active Directory. The application
is registered as a multi-tenant app.
You also need to create an app role (see documentation: How to: Add app roles in your application and receive them in the token ), lets call it read.weather
.
Other Tenant
and Logic App
To provide the Logic App
access to the API app
do this:
Enable a system assigned identity for the logic app
- ie use Managed Identity . Note down the system assigned managed identity Object ID
( {18a…}
), you will need it in a minute.
Create a service principal for the application
in the Other Tenant
using this command, where appId
is the appId of the application
registered in Home Tenant
(eg lets say it's {1a3}
here):
New-AzureADServicePrincipal -AppId {appId}
This command will output a json document which includes among other things an objectId
for the service principal just created.
[... more json ...]
"objectId": "b08{…}",
[... more json...]
You should also see the appRoles, including the app role read.weather
you just created, om the json output from the New-AzureADServicePrincipal
command:
[... more json...]
"appRoles": [
{
"allowedMemberTypes": [
"Application"
],
"description": "Read the weather.",
"displayName": "Read Weather",
"id": "46f{…}",
"isEnabled": true,
"value": "read.weather"
}
],
[... more json...]
New-AzureADServiceAppRoleAssignment -Id {app role ide} -ObjectId {system assigned identity object id} -PrincipalId {system assigned identity object id} -ResourceId {object id of service principal}
Eg something like this:
New-AzureADServiceAppRoleAssignment -Id 46f… -ObjectId 18a… -PrincipalId 18a… -ResourceId b08…
Logic App
using the URI to the API app
using Managed Identity for authentication. Notice that the audience is needed and has the form: api://{appId}
.
Does this mean that anyone could do this, if only they know the appId of your application
registration, and wouldn't this compromise the security of the API app
?
Yes, it does, and yes indeed it could compromise the security of the API app
.
If you look at the access token being created and used as bearer from the Logic App
it is a valid access token, which contains all the necessary claims, including the app role(s). The access token is however issued by Other Tenant
and not Home Tenant
.
Therefore, if you have a multi tenanted application and you want to guard it against this scenario, then you could check the issuer ( tid
more likely) of the incoming access token calling the API and only accept it if the issuer is the Home Tenant
, or you could make the application
a single tenant app.
Or, you could require that the issuer matches a list of tenants that the API trusts.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.