Short Scenrario: A muti tenant front end javascript (React.JS) Web Application calls a multi tenant ASP.NET Core 2.2 WebAPI from the browser.
Authentication:
ADAL.js in the front end app takes care of getting a token from either AzureAD1 or AzureAD2 or AzureAD3... when the User signs-in (based on the User's original Azure Active Directory).
The User gives consent to the front end Web App (scope: Sign in and read user profile) which is delegated to the WebAPI too. (meaning the user does not need to consent to the WebAPI as well)
The front end Web App calls the WebAPI with the bearer token to get the resources.
Problem: I must automate the deployment of a new environment. And set the manifest file accordingly (It's a SaaS solution)
This step will add a new object in the manifest file:
"preAuthorizedApplications": [
{
"appId": "guid",
"permissionIds": [
"guid"
]
}
],
How can I add this "preAuthorizedApplications" section into the manifest file using Azure PowerShell? Why is it available in the portal but not in PS yet? It's the other way around usually...
08-05-2019 Update based on the answer:
I am getting the access token via a Service Principal:
$adTokenUrl = "https://login.microsoftonline.com/$TenantId/oauth2/token"
$resource = "https://graph.windows.net/"
$body = @{
grant_type = "client_credentials"
client_id = "$ServicePrincipalId"
client_secret = "$ServicePrincipalKey"
resource = "$resource"
}
$response = Invoke-RestMethod -Method 'Post' -Uri $adTokenUrl -ContentType "application/x-www-form-urlencoded" -Body $body
$token = $response.access_token
According to the docs: https://docs.microsoft.com/en-us/graph/api/application-update?view=graph-rest-beta&tabs=cs
The Service Principal should have at least Application.ReadWrite.OwnedBy, and most Application.ReadWrite.All privileges.
Should I ask our AAD admin to grant the below rights to the Service Principal?
08-05-2019 Update 2: Service Principal has been granted with ALL of the highlighted rights above.
Attempt 1:
Step 1: getting an access_token via the Service Principal (Owner of the Api app to be updated)
$adTokenUrl = "https://login.microsoftonline.com/$(TenantId)/oauth2/token"
$resource = "https://graph.microsoft.com/"
$body = @{
grant_type = "client_credentials"
client_id = "$(ServicePrincipalId)"
client_secret = "$(ServicePrincipalKey)"
resource = "$resource"
}
$response = Invoke-RestMethod -Method 'Post' -Uri $adTokenUrl -ContentType "application/x-www-form-urlencoded" -Body $body
$token = $response.access_token
Step 2: using this access_token, building up my PATCH request as per Md Farid Uddin Kiron's suggestion, and
Result: The remote server returned an error: (403) Forbidden.
09-05-2019 Update 3: After some kind and detailed explanation and guidance, I got this to work and getting HTTP 204 for my Postman request. Only thing left is to integrate this steps into my pipeline.
See accepted answer. It works. If someone has the same issue, please read the other answer from Md Farid Uddin Kiron.
You are right, seems there is something faultiness exists in AzureAD powershell module. That not works for me too .
If you want to modify your app manifest
using powershell to add "preAuthorizedApplications" section, you can try the powershell script below.
I have tested on my side and it works for me.
In theory, I have called Microsoft Graph API to modify the app manifest
. If you have any further concerns, please feel free to let me know.
$AdAdminUserName = "<-your Azure ad admin username ->"
$AdAdminPass="<-your Azure ad admin password ->"
$AdAppObjId = "<-your app obj id->"
$AdPreAuthAppId = "<-the app that need to be pre authed ->"
$AdAppScopeId = "<-your app scope id->"
$tenantName = "<-your tenant name->"
$body=@{
"grant_type"="password";
"resource"="https://graph.microsoft.com/";
"client_id"="1950a258-227b-4e31-a9cf-717495945fc2";
"username"=$AdAdminUserName;
"password" = $AdAdminPass
}
$requrl = "https://login.microsoftonline.com/"+$tenantName+"/oauth2/token"
$result=Invoke-RestMethod -Uri $requrl -Method POST -Body $body
$headers = New-Object 'System.Collections.Generic.Dictionary[String,String]'
$headers.Add("Content-Type","application/json")
$headers.Add("Authorization","Bearer " + $result.access_token)
$preAuthBody = "{`"api`": {`"preAuthorizedApplications`": [{`"appId`": `"" + $AdPreAuthAppId + "`",`"permissionIds`": [`"" + $AdAppScopeId + "`"]}]}}"
$requrl= "https://graph.microsoft.com/beta/applications/"+$AdAppObjId
Invoke-RestMethod -Uri $requrl -Method PATCH -Body $preAuthBody -Headers $headers
Note: ROPC is not safe as Microsoft does not recommend to use that. It also does not allow to use MFA that is why it is little dangerous.
Hi @MdFaridUddinKiron! Many thanks for your suggestion! I will be testing this soon. As a workaround currently I am adding myself (with an objectId) as an owner in the PS script when I create the apps in AAD, so I can make the necessary changes accordingly after deployment in the Azure Portal manually.What I noticed that the
$AdAppScopeId
(permissionIds) is different for all my apps. The$AdPreAuthAppId
is clear, that's the object ID of the app. However I can't seem to find any documentation for scope id's. What I'm guessing now is that I can assign any valid GUID?just found it. It's the id of the oauth2Permissions in my case. docs.microsoft.com/en-us/graph/api/resources/…
Yeah you can. Let me know if you have any more concerned.
Hi @MdFaridUddinKiron! I have tested it finally. Unfortunatelly with an exception: The remote server returned an error: (405) Method Not Allowed. Seems like the PATCH verb is not allowed?
Hi, it is weird...I tested the script above in 2 tenants and it works for them all. In fact , I am calling this Graph API : docs.microsoft.com/en-us/graph/api/… As you can see, only PATCH method is supported ... could you pls have a check ? If the API is called successfully it will reply 204: no content