private string GenerateOutputToken(ClaimsRequestParameter claimsRequested, string requestClientId)
        {
            //This logic will re-issue the claims requested by Azure AD.
            //Insert here the specific logic for your custom providers
            List <Claim> claims = new List <Claim>();

            foreach (var claimRequested in claimsRequested.IdToken)
            {
                string claimValue = claimRequested.Value.Value ?? claimRequested.Value.Values?.FirstOrDefault();
                claims.Add(new Claim(claimRequested.Key, claimValue));
            }
            ;

            //JWT audience must match the client id that was requested
            string audience = requestClientId;

            string issuer = Settings.Default.ExtensionClaimsIssuer;

            //TODO: Add the configuration setting in your Azure Subscription or web.config file
            string           certWithPrivateKeyString = ConfigurationManager.AppSettings["ExtensionClaimsSigningCertificateString"];
            X509Certificate2 signingCert = new X509Certificate2(
                Convert.FromBase64String(certWithPrivateKeyString),
                (string)null,
                X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

            X509SecurityKey securityKey = new X509SecurityKey(signingCert)
            {
                KeyId = Base64UrlEncoder.Encode(signingCert.GetCertHash())
            };

            RSACryptoServiceProvider cryptoServiceProvider = (RSACryptoServiceProvider)signingCert.PrivateKey;
            SigningCredentials       signingCredentials    = new SigningCredentials(new RsaSecurityKey(cryptoServiceProvider), SecurityAlgorithms.RsaSha256);

            signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.RsaSha256);

            JwtSecurityToken jwtToken = new JwtSecurityToken
                                        (
                issuer: issuer,
                audience: audience,
                claims: claims,
                signingCredentials: signingCredentials,
                expires: DateTime.Now.AddDays(1)
                                        );

            JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
            string tokenString = tokenHandler.WriteToken(jwtToken);

            return(tokenString);
        }
        public HttpResponseMessage Index(AuthorizeModel azureAdAuthorizeRequest)
        {
            try
            {
                //Input Syntax Validation
                if (azureAdAuthorizeRequest.Id_Token_Hint == null)
                {
                    throw new InvalidDataException("id_token_hint is required.");
                }

                if (azureAdAuthorizeRequest.Response_Type != "id_token")
                {
                    throw new InvalidDataException("Unsupported response type.");
                }

                if (azureAdAuthorizeRequest.Response_Mode != "form_post")
                {
                    throw new InvalidDataException("Unsupported response mode.");
                }

                string requestClientId = azureAdAuthorizeRequest.Client_Id;

                //Validate the client id of the request is allowed
                if (!Settings.Default.AllowedExtensionClientIds.Contains(requestClientId))
                {
                    throw new InvalidDataException("Unauthorized client.");
                }

                if (!Settings.Default.AzureADAllowedRedirectUris.Contains(azureAdAuthorizeRequest.Redirect_Uri))
                {
                    throw new InvalidDataException("Unauthorized redirect uri.");
                }
                //End of input Syntax Validation

                //Validate and parse the original id_token_hint. We need to extract the 'sub' claim and reply it back
                JwtSecurityToken idTokenHint = ValidateIdTokenHint(azureAdAuthorizeRequest.Id_Token_Hint);
                string           originalSub = idTokenHint.Claims.First(c => c.Type == "sub").Value;

                //Analyze the claims requested by Azure AD into the provider
                //In this sample, we will simply echo back exactly what Azure AD Requested.
                //In real examples, the provider would execute some custom logic
                ClaimsRequestParameter requestedControlClaims = JsonConvert.DeserializeObject <ClaimsRequestParameter>(azureAdAuthorizeRequest.Claims);
                if (requestedControlClaims.IdToken == null)
                {
                    throw new InvalidDataException("Unsupported claims request parameter.");
                }

                //In addition to the Sub is required to be returned
                requestedControlClaims.IdToken.Add(
                    "sub", new ClaimsRequestParameter.ClaimProperties()
                {
                    Value = originalSub
                }
                    );

                //We will prepare the output here right away. If user interaction is required, return the proper redirections
                //to views to challenge user.
                NameValueCollection dataToSend = new NameValueCollection();
                dataToSend.Add("state", azureAdAuthorizeRequest.State);
                dataToSend.Add("id_token", GenerateOutputToken(requestedControlClaims, requestClientId));

                Uri    redirectUri = new Uri(azureAdAuthorizeRequest.Redirect_Uri);
                string formPost    = BuildFormPostWithDataToSend(dataToSend, redirectUri);

                var response = Request.CreateResponse(HttpStatusCode.OK);
                response.Content          = new StringContent(formPost, Encoding.UTF8, "text/html");
                response.Headers.Location = redirectUri;
                return(response);
            }
            catch (Exception e)
            {
                return(new HttpResponseMessage()
                {
                    Content = new StringContent(
                        JsonConvert.SerializeObject(e, Formatting.Indented, new JsonSerializerSettings {
                        NullValueHandling = NullValueHandling.Ignore
                    }),
                        Encoding.UTF8,
                        "application/json")
                });
            }
        }