Integrating OAuth2 with Canvas LMS in a .NET minimal API
Introduction
This blog aims to guide you through integrating OAuth2 with Canvas LMS within a .NET minimal API.
Setting Up the Minimal API Environment
Firs, ensure you have the latest version of .NET SDK installed on your development machine. We will leverage the minimal API features introduced in .NET 6 to create a lightweight and highly performant application.
Start by creating a new project:
dotnet new web -n CanvasOAuth2Integration
Navigate to the newly created project directory and open the project in your preferred IDE.
Configuring OAuth2 with Canvas LMS
In the Program.cs
file, begin by setting up the necessary namespaces and services for authentication:
using System.Net.Http.Headers;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OAuth;
These namespaces are essential for handling the OAuth2 flow and user authentication within our application.
Continue by configuring the OAuth2 settings in the appsettings.json
file. This includes the client ID, client secret, and API endpoints provided by Canvas LMS:
"Canvas": {
"ClientId": "<Your-Client-Id>",
"ClientSecret": "<Your-Client-Secret>",
"BaseApiUrl": "https://yourcanvasinstance.instructure.com/"
}
Ensure you replace <Your-Client-Id>
and <Your-Client-Secret>
with your actual credentials from Canvas.
Back in Program.cs
, integrate the OAuth2 authentication scheme with the following code snippet inside the var builder = WebApplication.CreateBuilder(args);
section:
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "Canvas";
})
.AddCookie()
.AddOAuth("Canvas", options =>
{
var canvasConfig = builder.Configuration.GetSection("Canvas");
options.ClientId = canvasConfig["ClientId"];
options.ClientSecret = canvasConfig["ClientSecret"];
options.CallbackPath = new PathString("/oauth-callback");
options.AuthorizationEndpoint = canvasConfig["BaseApiUrl"] + "login/oauth2/auth";
options.TokenEndpoint = canvasConfig["BaseApiUrl"] + "login/oauth2/token";
options.UserInformationEndpoint = canvasConfig["BaseApiUrl"] + "api/v1/users/self";
// Additional configuration...
});
This configuration sets up the authentication schemes and specifies the OAuth endpoints required for the Canvas LMS integration.
Handling User Information and Tokens
Within the .AddOAuth("Canvas", options => {...});
section, we need to handle user information and access tokens by implementing the OnCreatingTicket
event:
options.Events = new OAuthEvents
{
OnCreatingTicket = async context =>
{
var accessToken = context.AccessToken;
var requestMessage = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var client = context.Backchannel;
var response = await client.SendAsync(requestMessage, context.HttpContext.RequestAborted);
response.EnsureSuccessStatusCode();
var userJson = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
var name = userJson.RootElement.GetString("name");
if (context.Identity != null) context.Identity.AddClaim(new Claim(ClaimTypes.Name, name));
}
};
This code ensures that once a user successfully authenticates through Canvas, their information is fetched and processed appropriately within your application.
Defining Routes and Securing Endpoints
Now, let's define the routes for our application and secure them using the [Authorize]
attribute:
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
// Define a basic route as a sanity check
app.MapGet("/", () => "Hello, World!");
// Secure the Canvas user information endpoint
app.MapGet("/canvas", [Authorize] (HttpContext httpContext) =>
$"Canvas user information: {httpContext.User.Identity?.Name}");
// Define the login and logout routes
app.MapGet("/login", (HttpContext httpContext) =>
Results.Challenge(new AuthenticationProperties { RedirectUri = "/" }, "Canvas"));
app.MapGet("/logout", (HttpContext httpContext) =>
Results.SignOut(new AuthenticationProperties { RedirectUri = "/" }, CookieAuthenticationDefaults.AuthenticationScheme));
// Run the application
app.Run();
These endpoints provide basic functionality to authenticate with Canvas, check the logged-in user's information, and log out.
Testing the Application
Once you have set up your routes and authentication flow, it's important to test the application to ensure everything is working as expected:
- Run your application and navigate to the
/login
endpoint in your browser. - You should be redirected to the Canvas login page. Log in with your Canvas credentials.
- After successful login, you should be redirected back to your application's homepage (
/
route). - Navigate to the
/canvas
endpoint. You should see information about the logged-in Canvas user. - Finally, visit the
/logout
endpoint to log out of the application.
Ensure that each step works as expected and debug any issues that arise.
Best practices and additional considerations
While integrating OAuth2 with Canvas LMS in your .NET application, consider the following best practices:
- Secure your application: Ensure that your application is running over HTTPS, especially in production, to protect sensitive information transmitted during the authentication process.
- Manage secrets securely: Never hardcode sensitive information like your client ID and client secret in your code. Instead, use environment variables, secure app settings or a key vault.
- Error handling: Implement error handling and logging to capture and respond to any authentication or authorization issues.
- User experience: Design the authentication flow to be as seamless as possible for the end-user. Consider implementing session management and providing clear messages for authentication states.
Conclusion
In this blog, we've walked through setting up OAuth2 authentication with Canvas LMS in a .NET minimal API application. Remember, OAuth2 is a complex protocol, so always stay updated with the latest security practices and Canvas LMS updates.
For more detailed information, please read the official Canvas LMS API documentation and the OAuth2 specification. Happy coding!