protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            Logger.LogInformation($"Entering authentication process with {nameof(AzureAuthenticationHandler)}");

            if ((Context.User == null || Context.User.Identity == null || !Context.User.Identity.IsAuthenticated) &&
                (Context.Request.Path != $"/{Options.AuthMeEndpoint}" || Context.Request.Path != $"/{Options.AuthRefreshEndpoint}"))
            {
                try
                {
                    AzureAuthenticationResponse authResponse = await GetUserDetailsFromAzureAuthentication();

                    await GetRoleMembershipsForCurrentUser(authResponse);

                    AuthenticationTicket ticket = BuildAuthenticationTicketFromAuthenticationResponse(authResponse);

                    Logger.LogInformation("Setting context user to authenticated principal.");
                    Context.User = ticket.Principal;

                    Logger.LogInformation($"Authentication successful, exiting {nameof(AzureAuthenticationHandler)}");
                    return(AuthenticateResult.Success(ticket));
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, $"Failed to process identity in {nameof(AzureAuthenticationHandler)}");
                    return(AuthenticateResult.Fail(ex.Message));
                }
            }
            else
            {
                Logger.LogInformation($"Identity already set, nothing to process in {nameof(AzureAuthenticationHandler)}");
                return(AuthenticateResult.NoResult());
            }
        }
        private async Task GetRoleMembershipsForCurrentUser(AzureAuthenticationResponse userDetails)
        {
            string graphUrl = "https://graph.microsoft.com/v1.0/me/memberOf/$/microsoft.graph.group?$select=id,displayName,securityEnabled";

            HttpRequestMessage graphRequest = new HttpRequestMessage(HttpMethod.Get, graphUrl);

            graphRequest.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", userDetails.GraphAccessToken);
            Logger.LogInformation("Making call to MS Graph to get group memberships");

            using (HttpResponseMessage graphResponse = await _graphHttpClient.SendAsync(graphRequest))
            {
                if (!graphResponse.IsSuccessStatusCode)
                {
                    Logger.LogError($"Unable to fetch users group memberships. {graphResponse.StatusCode}");
                    throw new WebException($"Unable to fetch users group memberships. {graphResponse.StatusCode}");
                }

                string content = await graphResponse.Content.ReadAsStringAsync();

                try
                {
                    Logger.LogInformation("Parsing group memberships");
                    JToken result = JToken.Parse(content);
                    userDetails.GroupMemberships = result.Value <JArray>("value");
                }
                catch
                {
                    Logger.LogError("Could not retreive json from graph endpoint.");
                    throw new WebException("Could not retreive json from graph endpoint.");
                }
            }
        }
        private AuthenticationTicket BuildAuthenticationTicketFromAuthenticationResponse(AzureAuthenticationResponse userDetails)
        {
            string userId = userDetails.AuthMeResponse["user_id"].Value <string>();

            Logger.LogDebug("Building authentication ticket for user : {0}", userId);

            GenericIdentity identity = new GenericIdentity(userId);

            Logger.LogInformation("Adding claims from payload");

            List <Claim> claims = new List <Claim>();

            foreach (JToken claim in userDetails.AuthMeResponse["user_claims"])
            {
                claims.Add(new Claim(claim["typ"].ToString(), claim["val"].ToString()));
            }

            Logger.LogInformation("Adding claims for groups");

            foreach (JToken group in userDetails.GroupMemberships)
            {
                bool isSecurityGroup = group["securityEnabled"].Value <bool>();
                if (isSecurityGroup)
                {
                    claims.Add(new Claim(Constants.GroupsClaimType, group["id"].ToString()));
                }
            }

            Logger.LogInformation("Add claims to new identity");
            identity.AddClaims(claims);

            GenericPrincipal p = new GenericPrincipal(identity, null);

            return(new AuthenticationTicket(p, AzureAuthenticationDefaults.AuthenticationScheme));
        }