So my tool creates bits of user generated content, and it is very handy to be able to provide a url that links directly to one of those pieces of content. However I can't passes any arguments to the external tool definition that canvas uses to perform the basic lti launch
I want to be able to do something like this
I understand that canvas does not currently repackage GET params, from the launch link back into the basic_lti_launch, however I am looking for a solution that can achieve this same effect.
Is there any other way to accomplish this, where I can pass arbitrary url parameters thru to the external tool launch?
This needs to be a solution that doesn't require any admin rights, i.e. a student can generate the url for sharing etc..
Solved! Go to Solution.
Christopher Esbrandt wrote:
I'm not very experienced with Ruby (Canvas is my first real working with the language), so I didn't want to go into the code to supply and answer when I wouldn't be sure of its accuracy. Further, it doesn't do much good for those using Instructure-hosted instances as we're unable to modify the code.
It was more of a suggestion for someone who did have more experience to submit it as a patch.
The suggestion of a short url feature is good, but that also adds a requirement to store the short url identifier and it's target destination. If there's already a dynamic data storage method in place on the target system, which is most likely so since the target is an external tool system, this would be a minor thing to accommodate. It, however, the external tool system is actually a static data system the only authenticates access, this could prove more difficult since such a system wouldn't actually require dynamic data storage.
In all, I think it's brilliant, but I wanted to clarify it's requirements.
Glad you think so 🙂
Creating such a system is trivial: you only need a table with two columns (short_thing, actual_link) and a very short script (~10 lines of PHP if you wanted to go that route).
"However you cannot generate a link to a backend lti tool, because you won't be passing thru the canvas SSO process and the backend LTI tool will have no context as to who you are."
If the student is creating content inside your environment, and if you have specific sharing rules, would it make sense to manage content, sharing and associated rules from within your environment?
Have you considered providing a "dashboard" view in your app, which would include a list of shared content from within your app?
In other words, allow the student to access your app as a dashboard instead of an assignment. From the dashboard you can display both a list of assignments, and display a list of content that has been shared with them. You also now have control over how content is shared, and you are leveraging authentication.
ebook vendors use a similar approach: one entry point allowing students to find reading material as well as assignments enabled by the instructor. You might also need to provide an instructor dashboard, allowing the creation of assignments from your environment.
This approach adheres to the SSO issue you mention, and requires no special privs in Canvas. It also allows you to implement any proprietary business logic necessary to meet your requirements.
Just trying to brainstorm.
Here is the workaround that I ultimately settled upon .. and it is working well.
I created a page inside my application that acts as a redirector (lets call it deeplink); the code flow works like this
That's great, but it requires modifying the code, right? This is something that instructure-hosted customers can't really do.
Nope, it does not you to modify the code, and I have tested it with hosted it works just fine, you are just installing a different LTI app into the site that is hidden and serves as a redirector, similar to an openid auth flow.
This is a bit of a hackish solution. Don't get me wrong, it works, but its far from ideal. The user leaves Canvas via a standard HTTP(S) request, which then creates a cookie and redirects the user back to Canvas to access the external tool, which then uses the cookie to send the user to the desired location. It's, with my limited understanding on network security, a security nightmare.
Security isn't bad, b/c the link reflector doesn't do anything, and when it comes back the user is already full authenticated .. plus I am assuming that your backend application enforces the roles in accordance with the launch params.
You don't use the referrer information (that would be bad), you can either hard code it on the back end because the reflector lti endpoint url is stable across all courses/placements and doesn't change. Or you can look it up using the canvas rest API External Tools - Canvas LMS REST API Documentation
Also to be clear, put it in a cookie, or stuff it in a session .. 6of1halfdozentheother. It should be known that this is how a ton of sites funnel you through their login screen .. including .. canvas
Okay, but this is all really complicated.
Ideally, it would work out of the box, with no special configurations or hidden LTI links. I mentioned the relevant part of the code you'd need to change above, for someone who can program in Ruby. Maybe someone who understands the LTI specs can put in a feature request so it's done properly.
Alright, then does it work for people that don't have permission to access the point where the external tool is linked? If so, how'd you manage that? A user without permissions for an account or course will be unable to access practically anything from them.
Basically, a user not enrolled in course 42 cannot access content from course 42, unless they have higher permissions, like administrators.
Further, just testing accessing an external tool direct with administrative rights then normal student (enrolled) rights, I got the error:
Couldn't find valid settings for this tool
That's from accessing "/courses/:course_id/external_tools/:external_tool_id" directly. How'd you work around that? I got it for external tools with and without custom fields.
For a non-enrolled student account, I got the standard Unauthorized error.
I agree it would, but if it did .. I wouldn't have had to ask the community for work arounds..
also it's not that complicated, and doesn't require ruby .. it's 10 lines of java code .. probably 6 in php.