How can I verify a Service Principal has an App role if that role is granted to a group it belongs to?

195 Views Asked by At

I have a group in AzureAD that contains the service principals for a group of Azure ARC servers. I also have an App Registration for an API I own and have created an app role for it called Readers. I've assigned the group to the App role and have verified that in the Azure portal.

Now when I get a token from the Azure ARC identity endpoint for an individual service principal, the role does not appear as a claim in the token. I think this might be by design since the official docs say:

Currently, if you add a service principal to a group, and then assign an app role to that group, Azure AD doesn't add the roles claim to tokens it issues.

My questions is: How do I verify that the service principal has the correct role due to its group membership? Is there some workaround I can use?

1

There are 1 best solutions below

0
On

I created an Azure AD Application and added App role like below:

enter image description here

Now, I created an Azure AD Group and added Service Principal as member:

enter image description here

Assigned App role to the Azure AD Group:

enter image description here

My questions is: How do I verify that the service principal has the correct role due to its group membership? Is there some workaround I can use?

You can make use of below code to fetch the app roles assigned to the Service Principal:

using Azure.Identity;
using Azure.Core;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

class Program
{
    static async Task Main(string[] args)
    {
        string accessToken = "AccessToken";
        string servicePrincipalId = "ServicePrincipalObjID";

        var appRoles = await GetAppRolesAsync(accessToken, servicePrincipalId);

        foreach (var appRole in appRoles)
        {
            Console.WriteLine($"App role: " + $"{"Displayname:" + appRole.DisplayName}");
            Console.WriteLine($" {"Value:" + appRole.Value}");
            Console.WriteLine ($" {"Id:" + appRole.Id}" );
        }
    }

    public static async Task<List<AppRole>> GetAppRolesAsync(string accessToken, string servicePrincipalId)
    {
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

            var response = await client.GetAsync($"https://graph.microsoft.com/v1.0/servicePrincipals/{servicePrincipalId}/appRoles");

            if (!response.IsSuccessStatusCode)
            {
                throw new Exception($"Failed to get app roles: {response.StatusCode}");
            }

            var json = await response.Content.ReadAsStringAsync();
            var jsonObject = JObject.Parse(json);
            var jsonArray = jsonObject["value"].ToString();
            var appRoles = JsonConvert.DeserializeObject<List<AppRole>>(jsonArray);

            return appRoles;
        }
    }
    public class AppRole
    {
        [JsonProperty("id")]
        public string Id { get; set; }

        [JsonProperty("allowedMemberTypes")]
        public string[] AllowedMemberTypes { get; set; }

        [JsonProperty("description")]
        public string Description { get; set; }

        [JsonProperty("displayName")]
        public string DisplayName { get; set; }

        [JsonProperty("isEnabled")]
        public bool IsEnabled { get; set; }

        [JsonProperty("value")]
        public string Value { get; set; }
    }
}

The App role assigned to the Azure AD Application with the ID displayed successfully like below:

enter image description here

App role: Displayname:full_access
Value:full_access
Id: xxxxxx