0

I am using core 3.1 to connect to the canvas API, this is part of my code..

 services.AddAuthentication(config =>
            {
                config.DefaultAuthenticateScheme = "CanvasCookies";
                config.DefaultSignInScheme = "CanvasCookies";
                config.DefaultChallengeScheme = "CanvasLMS";
            })
                .AddCookie("CanvasCookies")
                .AddOAuth("CanvasLMS", config => 
                {
                    var canvas_domain = Configuration.GetValue<string>("Canvas:Domain");
                    var client_secret = Configuration.GetValue<string>("Canvas:Secret");
                    var client_id = Configuration.GetValue<string>("Canvas:Client_id");

                    config.ClientId = client_id;
                    config.ClientSecret = client_secret;
                    
                    config.CallbackPath = new PathString("/oauth/callback");
                    //config.Scope.Add("google.com")


                    config.AuthorizationEndpoint = $"{canvas_domain}login/oauth2/auth";
                    config.TokenEndpoint = $"{canvas_domain}login/oauth2/token";
                    config.UserInformationEndpoint = $"{canvas_domain}api/v1/users//courses";

                    config.SaveTokens = true;
         

                    config.Events = new OAuthEvents()
                    {
                        OnCreatingTicket = context =>
                        {
                            var accessToken = context.AccessToken;
                            var base64payload = accessToken.Split('.')[1];
                            var bytes = Convert.FromBase64String(base64payload);
                            var jsonPayload = Encoding.UTF8.GetString(bytes);
                            var claims = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonPayload);

                            foreach(var claim in claims)
                            {
                                context.Identity.AddClaim(new Claim(claim.Key, claim.Value));
                            }

                            return Task.CompletedTask;
                        }


this is the controller

 public class APICanvasController : Controller
    {

...
        [Authorize]
        public async Task<IActionResult> Secret()
        {
            var serverResponse = await AccessTokenRefreshWrapper(
                        () => SecuredGetRequest("https://localhost:44388/secret/index"));

            var apiResponse = await AccessTokenRefreshWrapper(
                () => SecuredGetRequest("https://localhost:44388/secret/index"));

            return View();
        }

        private async Task<HttpResponseMessage> SecuredGetRequest(string url)
        {
            var token = await HttpContext.GetTokenAsync("access_token");
            var client = _httpClientFactory.CreateClient();
            client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
            return await client.GetAsync(url);
        }

        public async Task<HttpResponseMessage> AccessTokenRefreshWrapper(
        Func<Task<HttpResponseMessage>> initialRequest)
        {
            var response = await initialRequest();

            if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
            {
                await RefreshAccessToken();
                response = await initialRequest();
            }

            return response;
        }

        private async Task RefreshAccessToken()
        {
          ...
        }
    }
}


when I execute the code I obtain this error

Exception: The oauth state was missing or invalid. Unknown location

Exception: An error was encountered while handling the remote login. Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()

Any idea what I am doing wrong?

Thanks

Maite
  • 65
  • 2
  • 11
  • Does this [post](https://stackoverflow.com/questions/57164127/the-oauth-state-was-missing-or-invalid-an-error-was-encountered-while-handling) answer your problem? – nunohpinheiro Jan 19 '21 at 23:42

1 Answers1

0

CallbackPath is not supposed to refer to a controller, it refers to a unique path handled by the auth middleware. It will redirect back to your controller when it's done.

"/oauth/callback" should handle oauth authentication result as a json instead of page.

Michael Wang
  • 3,782
  • 1
  • 5
  • 15
  • Thanks @Michael Wang I know this callback no redirect to the controller!, I am a bit lost, the only think that I know is my current token is expire, so I have to generate a new one. But I don't know how to do that! any suggest? – Maite Jan 22 '21 at 21:36
  • Hi, @Maite, Sorry for the late reply, I am not so familiar with canvaslms. Maybe you could try find solution in [canvaslms community](https://community.canvaslms.com/). – Michael Wang Jan 27 '21 at 05:14