This commit is contained in:
@@ -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()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user