This commit is contained in:
2019-09-25 18:27:15 +00:00
parent a8a7270377
commit 62a271ec66

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Threading.Tasks;
using System.Net.Http;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
namespace qbridge.Controllers
{
@@ -13,6 +14,10 @@ namespace qbridge.Controllers
[Produces("application/json")]
public class OAuthRedirectController : ControllerBase
{
public const string CLIENT_ID = "ABj70Wv5gDauFd9KgKFwuvpQjfzTwEgodEG8tnBbS8mSQhNrZJ";
public const string CLIENT_SECRET = "XUmJyvEcEuwQuyhARUAm0a8G3gzbEAeMiATCLyFZ";
public const string REDIRECT_URI = "https://localhost:5001/OAuthRedirect";
//used for discovery document
//https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.0
private readonly IHttpClientFactory _clientFactory;
@@ -54,53 +59,112 @@ namespace qbridge.Controllers
_clientFactory = clientFactory;
}
// Redirect endpoint
//Step 4 here: https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/openid-connect
[HttpGet]
public IActionResult Get([FromQuery]string state, [FromQuery]string code)
{
//https://localhost:5001/oauthredirect?state=bar&code=foo
return Content($"State: {state}, Code: {code}");
}
[HttpGet("Start")]
public async Task<IActionResult> GetAsync()
{
//GET THE DISCOVERY DOCUMENT
//Discovery document contains the actual current endpoints to use for various ops
await GetQBDiscoveryDocument();
if (DiscoveryDoc == null)
{
return Content($"<h1>Error - Unable to fetch Discovery document from QuickBooks Online</h1>Cannot proceed");
}
var authorizationEndpoint = DiscoveryDoc["authorization_endpoint"].Value<string>();
if (string.IsNullOrWhiteSpace(authorizationEndpoint))
var AuthorizationEndpoint = DiscoveryDoc["authorization_endpoint"].Value<string>();
if (string.IsNullOrWhiteSpace(AuthorizationEndpoint))
{
return Content($"<h1>Error - Unable to find AuthorizationEndpoint value in Discovery document from QuickBooks Online</h1>Cannot proceed");
}
//GET AUTHORIZATION CODE AND REDIRECT
string url = string.Empty;
var queryParams = new Dictionary<string, string>()
{
{"client_id", "ABj70Wv5gDauFd9KgKFwuvpQjfzTwEgodEG8tnBbS8mSQhNrZJ" },
{"client_id", CLIENT_ID },
{"scope", "openid" },
{"redirect_uri","https://localhost:5001/OAuthRedirect" },
{"redirect_uri",REDIRECT_URI },
{"response_type","code"},
{"state","MyUniqueStateID"}
};
url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(authorizationEndpoint, queryParams);
url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(AuthorizationEndpoint, queryParams);
return Redirect(url);
//will ask for login creds and permission then will redirect back to the Get method above with:
//will ask for login creds and permission then will redirect back to the Get method below with:
//State: MyUniqueStateID, Code: AB11569366500tshFDRPEuR28l4vTjpXWuwFldE44rMng98Gn9
//This Code value is the "Authorization code" that is then used to get the access token
//which in turn is *then* used to actually get the access token
//which is step 5 here: https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/openid-connect#step-5-exchange-authorization-code-to-obtain-id-token-and-access-token
}
// Redirect endpoint
//Step 4 here: https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/openid-connect
[HttpGet]
public async Task<IActionResult> GetAsync([FromQuery]string state, [FromQuery]string code)
{
//We arrive here after the user has logged in and now we should have the authorization code that can now be used to fetch the actual tokens we need
var TokenEndpoint = DiscoveryDoc["token_endpoint"].Value<string>();
if (string.IsNullOrWhiteSpace(TokenEndpoint))
{
return Content($"<h1>Error - Unable to find TokenEndpoint value in Discovery document from QuickBooks Online</h1>Cannot proceed");
}
//Step 5: Exchange authorization code for refresh and access tokens
//Get access token
//which is step 5 here: https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/openid-connect#step-5-exchange-authorization-code-to-obtain-id-token-and-access-token
var request = new HttpRequestMessage(HttpMethod.Post, TokenEndpoint);
request.Headers.Add("Accept", "application/json");
request.Headers.Add("User-Agent", "AyaNova-QBridge");
request.Headers.Add("Authorization", "Basic " + Base64Encode(CLIENT_ID + ":" + CLIENT_SECRET));
var bodyParams = new Dictionary<string, string>()
{
{"code", code },
{"redirect_uri", REDIRECT_URI },
{"grant_type","authorization_code"}
};
request.Content = new StringContent(JsonConvert.SerializeObject(bodyParams), System.Text.Encoding.UTF8, "application/json");
var client = _clientFactory.CreateClient();
var response = await client.SendAsync(request);
JObject AccessTokenObject = null;
if (response.IsSuccessStatusCode)
{
string data = await response.Content.ReadAsStringAsync();
AccessTokenObject = JObject.Parse(data);
}
else
{
AccessTokenObject = null;
}
return Content($"TOKEN: {AccessTokenObject.ToString()}");
//https://localhost:5001/oauthredirect?state=bar&code=foo
// return Content($"State: {state}, Code: {code}");
}
public static string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}
public async Task GetQBDiscoveryDocument()
{