Search code examples
blackboard

Not receiving access_token in three-legged oauth 2.0 flow in asp.net mvc (Blackboard Learn)


I have to implement three-legged authentication in ASP.NET MVC. I have followed the steps according to the Blackboard documentation, especially the link https://community.blackboard.com/docs/DOC-3976-three-legged-oauth

I have received authorization code by calling the REST API /learn/api/public/v1/oauth2/authorizationcode.After that according to the documentation (I followed the documentation exactly but I don't know what am I have been missing ), I built a POST request to /learn/api/public/v1/oauth2/token to get access_token but I am unable to get access_token.

Instead, access_token, I have been receiving a BadRequest. This means I am making a mistake to build my second request but I am unable to fix the problem. I haven't found any code sample in .NET to implement three legged authentication for Blackboard Learn. Could you please help me to resolve the issue?

This is my code to call both APIs to receive access_token.

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // GET /learn/api/public/v1/oauth2/authorizationcode

        Guid stateId = Guid.NewGuid();

        string applicationKey = "Application key goes here";

        string redirectUrl = string.Format("https://Blackboard Learn URL goes here/learn/api/public/v1/oauth2/authorizationcode" +

        "?redirect_uri=https://localhost:44300/Home/OAuth2Response&response_type=code&client_id={0}&scope=read&state={1}",

        applicationKey, stateId);

        Response.Redirect(redirectUrl, true);

        return View();
    }


    public async Task<bool> OAuth2Response(string code = null, string state = null, string error = null, string error_description = null)    
    {    
        bool success = true;  

        string json = string.Empty;

        string urlCommand = string.Format("/learn/api/public/v1/oauth2/token?code={0}&redirect_url=https://localhost:44300/Home/OAuth2Response", code);

        try    
        {    
            using (HttpClient client = new HttpClient())    
            {    
                var endpoint = new Uri("Blackboard Learn URL goes here" + urlCommand);


                var postData = new List<KeyValuePair<string, string>>();

                postData.Add(new KeyValuePair<string, string>("grant_type", "authorization_code"));    

                    HttpContent body = new FormUrlEncodedContent(postData);       

                // POST /learn/api/public/v1/oauth2/token

                using (HttpResponseMessage response = await client.PostAsync(endpoint, body)) // Problem is here    
                {    
                    if (response.IsSuccessStatusCode)

                    {

                        json = await response.Content.ReadAsStringAsync();

                    }

                    else

                    {

                        success = false;

                    }

                }

            }

        }

        catch (Exception err)

        {

            //hopefully we never end up here, log this exception for forensics

            success = false;

        }

        return success;    
    }    
}

NOTE: I can successfully receive an access_token in Postman tool.


Solution

  • Finally, the below code works perfectly for 3 legged authentications in ASP.NET MVC.

    public class HomeController : Controller
    {
        //https://blackboard.jiveon.com/docs/DOC-3976-three-legged-oauth 
    
        public ActionResult Index()
        {
            // GET /learn/api/public/v1/oauth2/authorizationcode
    
            Guid stateId = Guid.NewGuid();
    
            string applicationKey = "Application key goes here";
    
            string redirectUrl = string.Format("Blackboard Learn URL goes here/learn/api/public/v1/oauth2/authorizationcode" +
                "?redirect_uri=https://localhost:44300/Home/OAuth2Response&response_type=code&client_id={0}&scope=read&state={1}",
                applicationKey, stateId);
    
            Response.Redirect(redirectUrl, true);
    
            return View();
        }
    
    
        public async Task<bool> OAuth2Response(string code = null, string state = null, string error = null, string error_description = null)
        {
            bool success = true;
            string json = string.Empty;
            string urlCommand = string.Format("/learn/api/public/v1/oauth2/token?code={0}&redirect_uri=https://localhost:44300/Home/OAuth2Response", code);
    
            try
            {
                using (HttpClient client = new HttpClient())
                {
    
                    var endpoint = new Uri("Blackboard Learn URL goes here" + urlCommand);
                 
    
                    client.DefaultRequestHeaders.Accept.Clear();
    
                    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("client_id:client_secret")));                  
    
                    var postData = new List<KeyValuePair<string, string>>();
                    postData.Add(new KeyValuePair<string, string>("grant_type", "authorization_code")); 
    
                    HttpContent body = new FormUrlEncodedContent(postData);
    
    
                    using (HttpResponseMessage response = await client.PostAsync(endpoint, body))
                    {
    
                        if (response.IsSuccessStatusCode)
                        {
                            json = await response.Content.ReadAsStringAsync();
    
                            dynamic oauth2Result = Newtonsoft.Json.JsonConvert.DeserializeObject(json);     
    
                            string access_token = oauth2Result.access_token;
    
                            string refresh_token = oauth2Result.refresh_token;           }
                        else
                        {
                            success = false;
                        }
                    }
                }
            }
            catch (Exception err)            {
                //hopefully we never end up here, log this exception for forensics      
                success = false;
            }
            return success;           
        }     
    }