0

It seems I'm on a journey to first programmatically create an Azure application and then use Azure Management APIs to do create some resource. There's a new snag I'd like to ask from the community, how to do basically the PowerShell command New-AzureRmRoleAssignment -RoleDefinitionName Owner -ServicePrincipalName $adApp.ApplicationId.Guid using HttpClient (or some smarter method with the exact needed permissions using Microsoft Graph API libraries).

Trying to be a better person this time (being more around, providing code), I prepared a repo in GH, but the issue basically boils down to what kind of a URI should be used (here). The code is

var roleAssignment = $"{{something here}}";
var roleAssignementContent = new StringContent(roleAssignment, Encoding.UTF8, "application/json");
var roleAssignmentResponse = await client.PostAsync($"https://graph.windows.net/{tenants.value[0].tenantId}/applications/{createdApplication.appId}?api-version=1.6", roleAssignementContent).ConfigureAwait(false);
var roleAssignement = await roleAssignmentResponse.Content.ReadAsStringAsync().ConfigureAwait(false);

I fiddled with Graph API Explorer too if things were easier using it (or the libraries) but with less luck. Indeed, the ultimate goal is to create application programmatically so that it becomes possible to use Azure Management Libraries to make a deployment. That is, all in code from the beginning to an end.

(Also, the code is of throwaway quality, to provide a more functioning example only.)

Veksi
  • 3,556
  • 3
  • 30
  • 69

1 Answers1

2

New-AzureRmRoleAssignment is used to assign the specified RBAC role to the specified service principal , you could achieve that by using the Resource Manager create role assignment API:

  1. Get ObjectId of application service principal.

    if you have got the objectId of application service principal before , you could skip this step .If not , you could use Azure ad graph api to request an application's service principal by application id :

    GET https://graph.windows.net/<TenantID>/servicePrincipals?$filter=servicePrincipalNames/any(c:%20c%20eq%20'applicationID')&api-version=1.6 
    
    Authorization: Bearer eyJ0eXAiOiJK*****-kKorR-pg
    
  2. Get Azure RBAC role identifier

    To assign the appropriate RBAC role to your service principal, you must know the identifier of the Azure RBAC role(Owner in your scenario), you could call the Resource Manager role definition API to list all Azure RBAC roles and search then iterate over the result to find the desired role definition by name.:

    GET https://management.azure.com/subscriptions/ed0caab7-c6d4-45e9-9289-c7e5997c9241/providers/Microsoft.Authorization/roleDefinitions?$filter=roleName%20eq%20'Owner'&api-version=2015-07-01
    
    Authorization: Bearer 
    
  3. Assign the appropriate RBAC role to service principal:

    PUT https://management.azure.com/subscriptions/ed0caab7-c6d4-45e9-9289-c7e5997c9241/providers/Microsoft.Authorization/roleAssignments/16fca587-013e-45f2-a03c-cfc9899a6ced?api-version=2015-07-01 
    
    Authorization: Bearer eyJ0eXAiOiJKV1QiL*****FlwO1mM7Cw6JWtfY2lGc5
    Content-Type: application/json
    
    {
     "properties": {
       "roleDefinitionId": "/subscriptions/XXXXXXXXXXXXXXX/providers/Microsoft.Authorization/roleDefinitions/XXXXXXXXXXXXXXXXX",
       "principalId": "XXXXXXXXXXXXXXXXXXXXX"
       }
    }
    

    roleDefinitionId is the id you get in step 2 ,principalId is the objectId you get in step 1 . ed0caab7-c6d4-45e9-9289-c7e5997c9241 is the subscription id ,16fca587-013e-45f2-a03c-cfc9899a6ced is a new guid created for the new role assignment .

Please refer to below document for more details :

Use Resource Manager authentication API to access subscriptions

Nan Yu
  • 26,101
  • 9
  • 68
  • 148
  • I tried to follow your instructions, but I must be missing something as at https://github.com/veikkoeeva/AppCreator/blob/master/AppCreator/Program.cs#L300 the result from `step 3` is _Bad Request_. It stands to reason I've missed something, but I can't get into my head what that could be. Would you care to lend your eyes a bit still? – Veksi Jul 18 '17 at 20:59
  • To add to the previous one, it doesn't seem the URL is bad, the payload seem to be OK and it's not an authorization problem either. So, something in the call I seem to be unable to understand (currently). – Veksi Jul 18 '17 at 21:06
  • Please try use fiddler or developer tools to check what is the inner error message when performing the roleAssignments api . – Nan Yu Jul 19 '17 at 01:23
  • And you need to confirm `roleDefinitionId` and `principalId` is correct , in your code you used role id in request , please try to create a new guid for the new role assignment in request .(/roleAssignments/?api-version=2015-07-01) – Nan Yu Jul 19 '17 at 05:53
  • `{"error":{"code":"RoleAssignmentUpdateNotPermitted","message":"Tenant ID, application ID, principal ID, and scope are not allowed to be updated."}}` I suppose the problem in the earlier code was that I actually hadn't the right token, so I updated the code with that and got that information. I suppose there is a problem with the IDs (as you mention) or something else I'm not aware of yet. – Veksi Jul 19 '17 at 08:45
  • Please use a unique new Guid for the roleAssignments request ((/roleAssignments/?api-version=2015-07-01)) and try again . – Nan Yu Jul 19 '17 at 08:50
  • The random guid was the sticking point. Thanks a lot for going through this! I leave the fixed code available for the foreseeable future (even though it's a crummy piece of code at that). – Veksi Jul 19 '17 at 11:05