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 }); } }
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 }); } } }