示例#1
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));
        }
        public async Task <IActionResult> OnPost(int platformId, int?courseId = null)
        {
            if (IdToken.IsMissing())
            {
                return(BadRequest(new ProblemDetails
                {
                    Title = "Missing data",
                    Detail = $"{nameof(IdToken)} is missing."
                }));
            }

            if (!await ValidateToken(IdToken))
            {
                return(Unauthorized());
            }

            var handler = new JwtSecurityTokenHandler();
            var token   = handler.ReadJwtToken(IdToken);

            var messageType = token.Claims.SingleOrDefault(c => c.Type == Constants.LtiClaims.MessageType)?.Value;

            if (messageType != Constants.Lti.LtiDeepLinkingResponseMessageType)
            {
                return(BadRequest(new ProblemDetails
                {
                    Title = "Incorrect message format",
                    Detail = $"Expecting {Constants.Lti.LtiDeepLinkingResponseMessageType}, but found {messageType}."
                }));
            }

            var client = await _identityContext.Clients.SingleOrDefaultAsync(c => c.ClientId == token.Issuer);

            var tool = await _context.Tools.SingleOrDefaultAsync(t => t.IdentityServerClientId == client.Id);

            var platform = await _context.GetPlatformAsync(platformId);

            var course = courseId.HasValue ? await _context.GetCourseAsync(courseId.Value) : null;

            var ltiRequest   = new LtiDeepLinkingResponse(token.Payload);
            var contentItems = ltiRequest.ContentItems;

            if (contentItems != null)
            {
                foreach (var contentItem in contentItems)
                {
                    // Can only handle LTI Links
                    if (contentItem.Type != Constants.ContentItemTypes.LtiLink)
                    {
                        continue;
                    }

                    var ltiLink = (ILtiLinkItem)contentItem;

                    var resourceLink = new ResourceLink
                    {
                        CustomProperties = ltiLink.Custom.ToDatabaseString(),
                        Description      = ltiLink.Text,
                        Title            = ltiLink.Title,
                        Tool             = tool
                    };

                    if (course == null)
                    {
                        platform.ResourceLinks.Add(resourceLink);
                    }
                    else
                    {
                        course.ResourceLinks.Add(resourceLink);
                        course.GradebookColumns.Add(new GradebookColumn
                        {
                            Label        = ltiLink.LineItem?.Label ?? resourceLink.Title,
                            ResourceId   = ltiLink.LineItem?.ResourceId,
                            ResourceLink = resourceLink,
                            ScoreMaximum = ltiLink.LineItem?.ScoreMaximum ?? 100,
                            Tag          = ltiLink.LineItem?.Tag.IfMissingThen("Deep Link")
                        });
                    }
                }

                await _context.SaveChangesAsync();
            }

            return(Page());
        }