Authentication for Global Javascript based app

JosephRousseau
Partner
Partner
6
2427

I'm looking to build an app that integrates on all canvas pages for the student role and ideally would like to use LTI to accomplish this, but as LTI placement doesn't allow for space on every page and doesn't allow for the space I'm looking to occupy (right sidebar) I am currently building this app out using the global javascript functionality. I do still need to authenticate the user on my server for server side functions and this is where LTI really would have helped. I'm curious if anyone has any experience combining these two approaches and if there might be a way  to authenticate a global js based app using the LTI 1.3 protocol (from the global js context - so would have to be an api call or something).

If not (maybe I'm approaching this the wrong way), I know I can call the canvas api using the context of the currently logged in user, is there an easy way I could maybe pass a token or something that my server could authenticate the logged in user?

6 Comments
bbennett2
Community Champion

I've got some apps using OAuth to sign users in/out using their Canvas identity. I haven't looked at making it an LTI app yet, so I'm not sure that route will provide any benefit to you. 

If you go the OAuth route, when you sign a user in, their token is scoped to their account, so permissions are taken care of. But then you need some kind of persistent storage to manage tokens for each request. Plus, if you're making requests from the client and not the server, it isn't really necessary because their client scope is already enforced by Canvas.

JosephRousseau
Partner
Partner
Author

Hello,

 

Thanks for the response! I think oauth will work, the flow might be a bit awkward however because the "app" itself is embedded in the canvas page using the global js functionality. Or is this also what you are doing?

 

Yeah, I am not too worried about the scopes etc because I really just want to share the authentication context with my server so the student doesn't have to login again, I don't think I will need to call the canvas api's from my server at all. The problem with oauth is that they will still have to accept permissions whereas with LTI they can skip that step which is why I was trying to think of a way to do that so that it would be more seamless for the student.

It looks like there is a "sessionless LTI launch" api call (https://canvas.instructure.com/doc/api/external_tools.html#method.external_tools.generate_sessionles...) - not sure if that might do it for me.

James
Community Champion

Here is an approach that we use. It may not be suitable.

We use a single sign-on (SSO) solution and enable the app with the same credential requirements that Canvas has. When the student logs into the SSO, they get access to both Canvas and the other tools. I just use a regular hyperlink to the other tool since they get the identity from the SSO and not Canvas directly. There is no extra login prompt involved since they have already authenticated against the SSO.

I have used the sessionless LTI launch for other things. I was in a non-browser Node JS environment but needed to access an LTI tool (Roll Call Attendance). That allowed my Canvas access token to get access to the LTI, which required different credentials. There is a lot of overhead involved there so you may want to cache the credentials in a session or cookie so you don't have to launch it on every page. I'm not convinced this is the route you want to go, but I have never attempted to use LTI in the way you're describing.

I did find a thread here in the Community called LTI 1.3/Advantage login_required issue. The whole thread was helpful, but in particular, the post where Matthew Bucket explained the different uses of OAuth2 vs LTI 1.3 seemed like it might be helpful here.

JosephRousseau
Partner
Partner
Author

Thanks.

SSO would be interesting, but I'm not sure there's a standardized way across universities of implementing that, which would add some complexity to a multi university deployment.

 

Based on the linked post - I'm really looking for an LTI launch (users will be logged in and already in canvas where my js app will be embedded) - the reason I can't just use straight LTI is because they don't offer a placement on every page where I want it - which is why I'm forced to go the global JS route. Here's a screenshot of what I'm looking to accomplish - a sidebar (that opens and closes) on every page. I can get all of the canvas related api stuff directly on the page - but I do need to hit my own server for a few things like server generated tokens for chat functionality for instance.

I know they are authenticated with canvas, I just want to make I can verify they are authenticated on my server and make it as seamless as possible.

 

Screen Shot 2022-02-11 at 10.26.25 AM.png

James
Community Champion

@JosephRousseau 

I wasn't clear from your posts that you were looking for a multi-institution solution. I thought you were trying to get help with something from within your institution. You're right that the SSO solution wouldn't work if you're trying to support multiple instances.

We used to have Pronto installed that added itself to every page but only for certain courses (meaning they had to have some way of knowing which course it was in). Very few people used it and we dropped it, so I cannot do any testing or research. It used the custom global JavaScript to load the content from their servers. It is listed as an LTI with assignment and link selection placements, but those aren't what Pronto does, so I don't know if they were used. It might have been that we added Pronto to a sub-account's custom JavaScript, but I seem to remembering it getting loaded (but not showing) for all courses for a while. I do not remember it making additional network calls for LTI or OAuth.

Other things that we use (like Atomic Jolt search) load themselves on every page, but they just fetch their code from our custom JavaScript and then do everything on their end without a launch. We do have an LTI for them, with multiple placements, but that's not where their tool shows up. There are no LTI launches. However, when you make a search, it does have an authorization string that looks like a JWT with a bunch of information (mine was 13kB in size).

Whether they get a secret from the LTI or the developer keys, I'm not sure. I was able to decode it using jwt.io without putting in any signature, but then it complained about an invalid signature. It had a information in it about lti_roles, but it didn't appear to be an LTI launch.

JosephRousseau
Partner
Partner
Author

Thanks for that response @James !

Sorry, that's on me for not being clear enough!

 

Pronto is interesting in that they are doing the chat part (I have a couple additional tools planned for the sidebar) but instead of a drawer they are floating it on top. It's curious that they have no OAuth or LTI network calls - possibly they are just reducing the attack surface as much as possible and calling it good (client side key + restricting api calls to certain domains tied to those keys + maybe a few other possible "checks") without actually authenticating a particular user against their own server..

 

Atomic Jolt is also a nice tool - for that one it seems that they have a search bar that's loaded by the global js and the form action of the search bar points to the external tool url which redirects the user to the LTI tool so I am assuming they are using that for the authentication piece when they display the results. Or maybe mine is set up differently than yours?

 

A side note: I believe that the JWT will complain about the signature being invalid because although you can decode it, only the one who encoded will be able to decode it using their key without it complaining about signature. So anyone can read the JWT, but only the server that created it can verify that it hasn't been modified.