in src/Relecloud.Web.CallCenter/Startup.cs [173:240]
private void AddMicrosoftEntraIdServices(IServiceCollection services)
{
services.AddRazorPages().AddMicrosoftIdentityUI();
services.AddAuthorization(options =>
{
options.AddPolicy(Roles.Administrator, authBuilder =>
{
authBuilder.RequireRole(Roles.Administrator);
});
});
var builder = services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "MicrosoftEntraId")
.EnableTokenAcquisitionToCallDownstreamApi(new string[] { })
.AddDownstreamApi("relecloud-api", Configuration.GetSection("GraphBeta"));
// when using Microsoft.Identity.Web to retrieve an access token on behalf of the authenticated user
// you should use a shared session state provider.
// https://learn.microsoft.com/en-us/azure/active-directory-b2c/configure-authentication-sample-web-app-with-api?tabs=visual-studio#token-cache-for-a-web-app
if (string.IsNullOrEmpty(Configuration["App:RedisCache:ConnectionString"]))
{
builder.AddInMemoryTokenCaches();
}
else
{
builder.AddDistributedTokenCaches();
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.DisableL1Cache = true;
});
}
services.Configure<OpenIdConnectOptions>(Configuration.GetSection("MicrosoftEntraId"));
if (!Debugger.IsAttached)
{
// this sample uses AFD for the URL registered with Microsoft Entra ID to make it easier to get started
// but we recommend host name preservation for production scenarios
// https://learn.microsoft.com/en-us/azure/architecture/best-practices/host-name-preservation
services.Configure<ForwardedHeadersOptions>(options =>
{
// not needed when using host name preservation
options.ForwardedHeaders = ForwardedHeaders.XForwardedHost | ForwardedHeaders.XForwardedProto;
});
services.Configure((Action<MicrosoftIdentityOptions>)(options =>
{
var frontDoorHostname = Configuration["App:FrontDoorHostname"];
var callbackPath = Configuration["MicrosoftEntraId:CallbackPath"];
options.Events.OnTokenValidated += async ctx =>
{
await CreateOrUpdateUserInformation(ctx);
};
options.Events.OnRedirectToIdentityProvider += ctx =>
{
// not needed when using host name preservation
ctx.ProtocolMessage.RedirectUri = $"https://{frontDoorHostname}{callbackPath}";
return Task.CompletedTask;
};
options.Events.OnRedirectToIdentityProviderForSignOut += ctx =>
{
// not needed when using host name preservation
ctx.ProtocolMessage.PostLogoutRedirectUri = $"https://{frontDoorHostname}";
return Task.CompletedTask;
};
}));
}
}