private static async Task <SecurityKey> GetSecurityKey(PowerAppsPortalsOptions options)
        {
            string content = null;

            using (var client = new HttpClient())
            {
                var response = await client.GetAsync($"https://{options.Domain}/_services/auth/publickey").ConfigureAwait(false);

                content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            }

            var rs256Token = content.Replace("-----BEGIN PUBLIC KEY-----", "");

            rs256Token = rs256Token.Replace("-----END PUBLIC KEY-----", "");
            rs256Token = rs256Token.Replace("\n", "");
            var keyBytes = Convert.FromBase64String(rs256Token);

            var asymmetricKeyParameter = PublicKeyFactory.CreateKey(keyBytes);
            var rsaKeyParameters       = (RsaKeyParameters)asymmetricKeyParameter;

            var rsa           = new RSACryptoServiceProvider();
            var rsaParameters = new RSAParameters
            {
                Modulus  = rsaKeyParameters.Modulus.ToByteArrayUnsigned(),
                Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned()
            };

            rsa.ImportParameters(rsaParameters);

            return(new RsaSecurityKey(rsa));
        }
        public static AuthenticationBuilder AddPowerAppsPortalAuthentication(this IServiceCollection services, Action <PowerAppsPortalsOptions> configureOptions)
        {
            PowerAppsPortalsOptions powerappsPortalOptions = new PowerAppsPortalsOptions();

            configureOptions(powerappsPortalOptions);

            return(services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
                   .AddJwtBearer(options =>
            {
                // JwtBearerEvents available for debugging or additional modification
                options.Events = new JwtBearerEvents
                {
                    OnAuthenticationFailed = context =>
                    {
                        return Task.FromResult(0);
                    },
                    OnChallenge = context =>
                    {
                        return Task.FromResult(0);
                    },
                    OnMessageReceived = context =>
                    {
                        return Task.FromResult(0);
                    },
                    OnTokenValidated = context =>
                    {
                        return Task.FromResult(0);
                    },
                };
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    // Clock skew compensates for server time drift.
                    // We recommend 5 minutes or less:
                    ClockSkew = TimeSpan.FromMinutes(5),
                    // Specify the key used to sign the token:
                    RequireSignedTokens = true,
                    IssuerSigningKey = GetSecurityKey(powerappsPortalOptions).Result,
                    // Ensure the token hasn't expired:
                    RequireExpirationTime = true,
                    ValidateLifetime = true,
                    // Ensure the token audience matches our audience value (default true):
                    ValidateAudience = false,
                    ValidAudience = powerappsPortalOptions.ApplicationId,
                    // Ensure the token was issued by a trusted authorization server (default true):
                    ValidateIssuer = true,
                    ValidIssuer = powerappsPortalOptions.Domain
                };
            }));
        }