private void AddMicrosoftEntraIdServices()

in src/Relecloud.Web.CallCenter/Startup.cs [186:253]


        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[] { })
               .AddDownstreamWebApi("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;
                    };
                }));
            }
        }