Ejemplo n.º 1
0
        /// <summary>
        /// Handle the LTI request to launch deep linking. The token was validated by the Tool page.
        /// </summary>
        /// <returns></returns>
        public IActionResult OnPost()
        {
            if (string.IsNullOrEmpty(IdToken))
            {
                Error = $"{nameof(IdToken)} is missing or empty";
                return(Page());
            }

            var handler = new JwtSecurityTokenHandler();

            Token      = handler.ReadJwtToken(IdToken);
            LtiRequest = new LtiDeepLinkingRequest(Token.Payload);

            // Fill the catalog with choices
            if (LtiRequest.Context == null)
            {
                Activities = new List <Activity>
                {
                    new Activity
                    {
                        Id          = 1,
                        Title       = "Reports",
                        Description = "Reporting tool for admins.",
                        Selected    = false
                    }
                };
            }
            else
            {
                Activities = GenerateActivities(12);
            }

            return(Page());
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Build and send the deep linking response.
        /// </summary>
        /// <returns></returns>
        public async Task <IActionResult> OnPostAssignActivities()
        {
            var handler = new JwtSecurityTokenHandler();

            Token      = handler.ReadJwtToken(IdToken);
            LtiRequest = new LtiDeepLinkingRequest(Token.Payload);

            var response = new LtiDeepLinkingResponse
            {
                Data         = LtiRequest.DeepLinkingSettings.Data,
                DeploymentId = LtiRequest.DeploymentId
            };

            var contentItems     = new List <ContentItem>();
            var customParameters = LtiRequest.Custom;

            foreach (var activity in Activities)
            {
                if (activity.Selected)
                {
                    var contentItem = new LtiLinkItem
                    {
                        Title  = activity.Title,
                        Text   = activity.Description,
                        Url    = Url.Page("./Tool", null, null, Request.Scheme),
                        Custom = new Dictionary <string, string>
                        {
                            { "activity_id", activity.Id.ToString() }
                        }
                    };

                    if (customParameters != null)
                    {
                        foreach (var keyValue in LtiRequest.Custom)
                        {
                            contentItem.Custom.TryAdd(keyValue.Key, keyValue.Value);
                        }
                    }

                    contentItems.Add(contentItem);
                }
            }

            response.ContentItems = contentItems.ToArray();
            response.AddClaim(new Claim(JwtRegisteredClaimNames.Iss, LtiRequest.Aud[0]));
            response.AddClaim(new Claim(JwtRegisteredClaimNames.Aud, LtiRequest.Iss));
            response.AddClaim(new Claim(JwtRegisteredClaimNames.Sub, LtiRequest.Sub));
            response.AddClaim(new Claim(JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(DateTime.UtcNow).ToString()));
            response.AddClaim(new Claim(JwtRegisteredClaimNames.Nbf, EpochTime.GetIntDate(DateTime.UtcNow.AddSeconds(-5)).ToString()));
            response.AddClaim(new Claim(JwtRegisteredClaimNames.Exp, EpochTime.GetIntDate(DateTime.UtcNow.AddMinutes(5)).ToString()));
            response.AddClaim(new Claim(JwtRegisteredClaimNames.Nonce, IdentityModel.CryptoRandom.CreateRandomKeyString(8)));

            var platform = await _context.GetPlatformByIssuerAsync(LtiRequest.Iss);

            var credentials = PemHelper.SigningCredentialsFromPemString(platform.PrivateKey);
            var jwt         = handler.WriteToken(new JwtSecurityToken(new JwtHeader(credentials), response));

            return(Post("id_token", jwt, LtiRequest.DeepLinkingSettings.DeepLinkReturnUrl));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns the LTI claims for an LtiDeepLinkingRequest.
        /// </summary>
        /// <param name="tool">The deep linking tool.</param>
        /// <param name="person">The person being authorized.</param>
        /// <param name="course">The course (can be null).</param>
        /// <param name="platform">The platform.</param>
        /// <returns></returns>
        private List <Claim> GetDeepLinkingRequestClaims(
            Tool tool,
            Person person,
            Course course,
            Platform platform)
        {
            var httpRequest = _httpContextAccessor.HttpContext.Request;

            var request = new LtiDeepLinkingRequest
            {
                DeploymentId       = tool.DeploymentId,
                FamilyName         = person.LastName,
                GivenName          = person.FirstName,
                LaunchPresentation = new LaunchPresentationClaimValueType
                {
                    DocumentTarget = DocumentTarget.Window,
                    Locale         = CultureInfo.CurrentUICulture.Name
                },
                Lis = new LisClaimValueType
                {
                    PersonSourcedId        = person.SisId,
                    CourseSectionSourcedId = course?.SisId
                },
                Lti11LegacyUserId = person.Id.ToString(),
                Platform          = new PlatformClaimValueType
                {
                    ContactEmail      = platform.ContactEmail,
                    Description       = platform.Description,
                    Guid              = platform.Id.ToString(),
                    Name              = platform.Name,
                    ProductFamilyCode = platform.ProductFamilyCode,
                    Url     = platform.Url,
                    Version = platform.Version
                },
                Roles         = PeopleModel.ParsePersonRoles(person.Roles),
                TargetLinkUri = tool.DeepLinkingLaunchUrl
            };

            // Add the context if the launch is from a course.
            if (course == null)
            {
                // Remove context roles
                request.Roles = request.Roles.Where(r => !r.ToString().StartsWith("Context")).ToArray();
            }
            else
            {
                request.Context = new ContextClaimValueType
                {
                    Id    = course.Id.ToString(),
                    Title = course.Name,
                    Type  = new[] { ContextType.CourseSection }
                };
            }

            // Add the deep linking settings
            request.DeepLinkingSettings = new DeepLinkingSettingsClaimValueType
            {
                AcceptPresentationDocumentTargets = new [] { DocumentTarget.Window },
                AcceptMultiple    = true,
                AcceptTypes       = new [] { Constants.ContentItemTypes.LtiLink },
                AutoCreate        = true,
                DeepLinkReturnUrl = _linkGenerator.GetUriByPage(
                    "/DeepLinks",
                    handler: null,
                    values: new { platformId = platform.Id, courseId = course?.Id },
                    scheme: httpRequest.Scheme,
                    host: httpRequest.Host)
            };

            // Collect custom properties
            if (tool.CustomProperties.TryConvertToDictionary(out var custom))
            {
                // Prepare for custom property substitutions
                var substitutions = new CustomPropertySubstitutions
                {
                    LtiUser = new LtiUser
                    {
                        Username = person.Username
                    }
                };

                request.Custom = substitutions.ReplaceCustomPropertyValues(custom);
            }

            return(new List <Claim>(request.Claims));
        }