Search code examples
azureazure-app-configurationmicrosoft-identity-web

How do I Read/Write configuration data in Azure App Configuration from a Blazor app using the logged in user's credentials?


I am building a web portal for managing the values in some of our Azure App Configuration stores, to provide a user-friendly editor for some complex json-configuration values.

I think I have all the setup required, but am only getting 401 or 403 responses when actually using the client. Documentation for this use case seems to be lacking, so I hope someone could give some guidance on how to implement this.

Some relevant code snippets:

Editor.razor

@using Microsoft.Identity.Web
@inject MicrosoftIdentityConsentAndConditionalAccessHandler ConsentHandler
@inject ConfigurationService ConfigurationService
<editor/>
@code{
   private object Value { get; set; }
   protected override async Task OnInitializedAsync()
   {
     try
     {
       Value = await ConfigurationService.GetSettings();
     }
     catch (Exception ex)
     {
       ConsentHandler.HandleException(ex);
     }
     await base.OnInitializedAsync();
}

ConfigurationService.cs

using Azure.Data.AppConfiguration;
using Microsoft.Extensions.Options;
using Microsoft.Identity.Web;

private readonly ConfigurationClient _client;

public ConfigurationClient(IOptions<ConfigurationSettings> options, ITokenAcquisition tokenAcquisition)
{
  _client = new ConfigurationClient(new Uri(options.Value.Endpoint), new TokenAcquisitionTokenCredential(tokenAcquisition));
}

public async Task<object> GetSettings()
{
  return await ConfigurationClient.GetConfigurationSettingAsync("key");
}

Program.cs

//code
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
  .AddMicrosoftIdentityWebApp(configuration.GetSection("AzureAd"))
  .EnableTokenAcquisitionToCallDownstreamApi(new []{"User.Read"})
  .AddInMemoryTokenCaches();

builder.Services.AddControllersWithViews()
  .AddMicrosoftIdentityUI();

builder.Services.AddAuthorization(options =>
{
  options.FallbackPolicy = options.DefaultPolicy;
});

builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor()
  .AddMicrosoftIdentityConsentHandler();
//more code

appsettings.json

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "redacted.onmicrosoft.com",
    "TenantId": "redacted",
    "ClientId": "redacted",
    "ClientSecret": "redacted",
    "CallbackPath": "/signin-oidc"
  }
}

The web app is registered in Azure AD, with Authentication set up and functioning. I have created a client secret and am using that in the app configuration. No token configuration is set. API permissions are as follows: Azure AD API Permissions No settings have been defined under the "Expose an API" tab.

The user I am testing this with is my own, and has the "Contributor" role on the Azure App Configuration resource.

The website allows logging in, and on visiting the relevant page correctly requests the user's permission to access the App Configuration resource. Inspecting traffic reveals the app requests an access token with the .default scope on the configuration resource, and receives one successfully. Using the token results in a 403 forbidden.


Solution

  • The "Contributor" role won't give you access to the data in App Configuration. You need to grant yourself the App Configuration Data Owner role. More details can be found in the document below:

    https://learn.microsoft.com/en-us/azure/azure-app-configuration/concept-enable-rbac#azure-built-in-roles-for-azure-app-configuration