Example #1
0
        public async Task <CallbackResult> VerifyCallback(string redirectUri, string appID, string appSecret)
        {
            // state check
            var isStateCorrect = _stateHashingService.VerifyHashAgainstCookie();

            if (!isStateCorrect)
            {
                return new CallbackResult {
                           IsSuccessful = false, Message = "State did not match for Facebook.", ProviderType = ProviderType.Facebook
                }
            }
            ;

            // verify OAuth code
            var    code = _httpContextAccessor.HttpContext.Request.Query["code"];
            var    urlEncodedRedirect = HttpUtility.UrlEncode(redirectUri);
            string userInfoText       = string.Empty;

            using (var client = new HttpClient())
            {
                try
                {
                    var result = await client.GetAsync($"{FacebookEndpoints.OAuthAccessTokenBaseUrl}?client_id={appID}&redirect_uri={urlEncodedRedirect}&client_secret={appSecret}&code={code}");

                    if (!result.IsSuccessStatusCode)
                    {
                        return new CallbackResult {
                                   IsSuccessful = false, Message = $"Facebook OAuth failed: {result.StatusCode}", ProviderType = ProviderType.Facebook
                        }
                    }
                    ;
                    // get the profile info
                    var text = await result.Content.ReadAsStringAsync();

                    var idToken          = JObject.Parse(text).Root.SelectToken("access_token").ToString();
                    var userInfoResponse = await client.GetAsync($"{FacebookEndpoints.ProfileBaseUrl}?access_token={idToken}&fields=id,name,email");

                    if (!userInfoResponse.IsSuccessStatusCode)
                    {
                        var errorText = await userInfoResponse.Content.ReadAsStringAsync();

                        var errorMessage = JObject.Parse(errorText).SelectToken("error.message");
                        return(new CallbackResult {
                            IsSuccessful = false, Message = $"Facebook profile retrieval failed: {result.StatusCode}, {errorMessage}", ProviderType = ProviderType.Facebook
                        });
                    }
                    // parse the profile result
                    userInfoText = await userInfoResponse.Content.ReadAsStringAsync();
                }
                catch (HttpRequestException exception)
                {
                    return(new CallbackResult {
                        IsSuccessful = false, Message = $"Callback for Facebook data failed: {exception.Message}", ProviderType = ProviderType.Facebook
                    });
                }
            }
            var properties     = JObject.Parse(userInfoText).Values().Select(x => new { x.Path, Value = x.Value <string>() }).ToList();
            var facebookResult = new ResultData
            {
                ID    = properties.FirstOrDefault(x => x.Path == "id")?.Value,
                Email = properties.FirstOrDefault(x => x.Path == "email")?.Value,
                Name  = properties.FirstOrDefault(x => x.Path == "name")?.Value
            };

            return(new CallbackResult {
                IsSuccessful = true, Message = string.Empty, ResultData = facebookResult, Claims = new Claim[] {}, ProviderType = ProviderType.Facebook
            });
        }
    }
Example #2
0
        public async Task <CallbackResult> VerifyCallback(string redirectUri, string clientID, string clientSecret)
        {
            // state check
            var isStateCorrect = _stateHashingService.VerifyHashAgainstCookie();

            if (!isStateCorrect)
            {
                return new CallbackResult {
                           IsSuccessful = false, Message = "State did not match for OAuth2.", ProviderType = ProviderType.OAuth2
                }
            }
            ;

            // get JWT
            var code   = _httpContextAccessor.HttpContext.Request.Query["code"];
            var values = new Dictionary <string, string>
            {
                { "code", code },
                { "client_id", clientID },
                { "client_secret", clientSecret },
                { "redirect_uri", redirectUri },
                { "grant_type", "authorization_code" }
            };
            HttpResponseMessage result;

            using (var client = new HttpClient())
            {
                try
                {
                    result = await client.PostAsync(AccessTokenUrl, new FormUrlEncodedContent(values));
                }
                catch (HttpRequestException exception)
                {
                    return(new CallbackResult {
                        IsSuccessful = false, Message = $"Callback for token failed: {exception.Message}", ProviderType = ProviderType.OAuth2
                    });
                }
            }
            if (!result.IsSuccessStatusCode)
            {
                return new CallbackResult {
                           IsSuccessful = false, Message = $"OAuth2 failed: {result.StatusCode}", ProviderType = ProviderType.OAuth2
                }
            }
            ;

            // parse results
            var text = await result.Content.ReadAsStringAsync();

            var idToken = JObject.Parse(text).Root.SelectToken("id_token").ToString();
            var handler = new JwtSecurityTokenHandler();
            var token   = handler.ReadJwtToken(idToken);

            if (token.Claims == null)
            {
                throw new Exception("OAuth token has no claims");
            }
            var resultModel = new ResultData
            {
                ID    = token.Claims.FirstOrDefault(x => x.Type == "sub")?.Value,
                Name  = token.Claims.FirstOrDefault(x => x.Type == "name")?.Value,
                Email = token.Claims.FirstOrDefault(x => x.Type == "email")?.Value
            };

            return(new CallbackResult {
                IsSuccessful = true, ResultData = resultModel, Claims = token.Claims, ProviderType = ProviderType
            });
        }
    }
}