skip to Main Content

In my ASP.NET MVC Core project, I want all the AppRoles that are set up in the App Registration as a list to display in my view.

Currently I have attempted the following:

var servicePrincipal = await _graphServiceClient.Applications[_configuration["AzureAd:AppRegistrationId"]]
            .Request()
            .Select("appRoles")
            .GetAsync();

I have granted the application the API permissions Application.Read.All and Directory.Read.All, but I still get error:

ServiceException: Code: Authorization_RequestDenied
Message: Insufficient privileges to complete the operation

Questions:

  1. Am I even on the right path to achieve what I want and just missing the correct permission?
    • Does anyone know what permission is required then?
  2. Is there a different way to achieve this task?
    • I have attempted getting the roles out of the claim, but that only displays the user’s roles, not all the roles that are set up on the App Registration

Thank you in advance for any assistance!

3

Answers


  1. Chosen as BEST ANSWER

    While this is not a direct answer to my original question, I ended resolving the issue by using a different approach.

    I used the package Microsoft.Graph.Auth to generate a credential, then connect to Graph with that credential (basically connect as my Application Registration). Here's the function:

    public async Task<List<string>> GetGraphApiClient(IConfiguration configuration)
        {
            // Configure application
            var clientApplication = ConfidentialClientApplicationBuilder
                .Create(configuration["AzureAd:ClientId"])
                .WithTenantId(configuration["AzureAd:TenantId"])
                .WithClientSecret(configuration["AzureAd:ClientSecret"])
                .Build();
    
            // Create ClientCredentialProvider that will manage auth token for you
            var authenticationProvider = new ClientCredentialProvider(clientApplication);
            var graphClient = new GraphServiceClient(authenticationProvider);
    
            // Call Graph API
            var application = await graphClient.Applications[<"Application object ID here">].Request().GetAsync();
    
            List<string> appRoles = new List<string>();
            foreach (var app in application.AppRoles)
            {
                appRoles.Add(app.DisplayName);
            }
            return appRoles;
        }
    

    Probably not the best way, but works, so I am happy.


  2. Based on the documentation here, Application.Read.All is the right permission to read information about an application.

    I believe the reason you are getting this error is because you have assigned this permission to your application but it seems the user who’s making the Graph API request does not have that permission.

    Please check the permissions assigned to the user who’s making the request and make sure that they have the appropriate permissions to make this request.

    Login or Signup to reply.
  3. looks like I’m late…

    I test with delegated permission and application permission, both of them are ok.

    for application permission, it would be easy to do it with code like below:

    using Microsoft.Graph;
    using Azure.Identity;
    
    var scopes = new[] { "https://graph.microsoft.com/.default" };
    var tenantId = "tenantId ";
    var clientId = "clientId ";
    var clientSecret = "clientSecret ";
    var clientSecretCredential = new ClientSecretCredential(
                                tenantId, clientId, clientSecret);
    var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
    
    var res = await graphClient.Applications["azure_ad_app_object_id_instead_of_client_id"].Request().GetAsync();
    var roles = res.AppRoles;
    

    This requires application type of api permission:

    enter image description here

    If we want to use the delegated api permission, since this is an MVC application, we need to integrate AAD authentication into the application first. We can follow this sample. To generally speaking, add codes in program.cs like this:

    builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration) .EnableTokenAcquisitionToCallDownstreamApi() .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi")) .AddInMemoryTokenCaches();

    builder.Services.AddControllersWithViews(options =>
    {
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
        options.Filters.Add(new AuthorizeFilter(policy));
    }).AddMicrosoftIdentityUI();
    
    "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "Domain": "TenantId",
        "TenantId": "TenantId",
        "ClientId": "ClientId",
        "ClientSecret": "ClientSecret",
        "CallbackPath": "/home", //don't forget to set redirect url in azure portal
        "SignedOutCallbackPath ": "/signout-callback-oidc"
      },
    

    Then inject graphclient into the code and use it call graph api,

    private readonly GraphServiceClient _graphServiceClient;
    
    public HomeController(GraphServiceClient graphServiceClient)
    {
        _graphServiceClient = graphServiceClient;
    }
    
    public async Task<IActionResult> IndexAsync() {
        var b = await _graphServiceClient.Applications["aad_app_object_id"].Request().GetAsync();
        return View();
    }
    

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search