diff --git a/lti_consumer/lti_consumer.py b/lti_consumer/lti_consumer.py
index e3262e97c89de4fd29c4283f7363635ee69849d6..9b34124023d570f6bebe6f7e5115a83389e64b49 100644
--- a/lti_consumer/lti_consumer.py
+++ b/lti_consumer/lti_consumer.py
@@ -675,6 +675,16 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
             return 'problem'
         return 'other'
 
+    @property
+    def external_user_id(self):
+        """
+        Returns the opaque external user id for the current user.
+        """
+        user_id = self.runtime.service(self, 'user').get_external_user_id('lti')
+        if user_id is None:
+            raise LtiError(self.ugettext("Could not get user id for current request"))
+        return six.text_type(six.moves.urllib.parse.quote(user_id))
+
     @property
     def resource_link_id(self):
         """
@@ -976,7 +986,7 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
 
         # Pass user data
         lti_consumer.set_user_data(
-            user_id=self.runtime.user_id,
+            user_id=self.external_user_id,
             # Pass django user role to library
             role=self.runtime.get_user_role()
         )
@@ -996,10 +1006,7 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
             )
         })
 
-        context.update({
-            'launch_url': self.lti_1p3_launch_url,
-            'user': self.runtime.user_id
-        })
+        context.update({'launch_url': self.lti_1p3_launch_url})
         template = loader.render_mako_template('/templates/html/lti_1p3_launch.html', context)
         return Response(template, content_type='text/html')