2015-04-23 48 views
1

我正在試圖在我們的教育平臺中實現LTI,以便與Java中的QTIWoks連接。QTIWorks LTI請求參數爲空

我有一個簡單的工具,消費者產生下面的HTML表單:

<html> 
<head> </head> 
<body> 
<form action="http://192.168.0.114:8080/qtiworks-engine/lti/domainlaunch" name="ltiLaunchForm" id="ltiLaunchForm" method="post" target="basicltiLaunchFrame" enctype="application/x-www-form-urlencoded" style="display: block;"> 
<input type="hidden" name="context_id" value="cid-00113"> 
<input type="hidden" name="context_label" value="SI106"> 
<input type="hidden" name="context_title" value="Design of Personal Environments 1"> 
<input type="hidden" name="ext_note" value="Instructor from first course"> 
<input type="hidden" name="launch_presentation_locale" value="en_us"> 
<input type="hidden" name="lis_person_contact_email_primary" value="[email protected]"> 
<input type="hidden" name="lis_person_name_family" value="Instructor"> 
<input type="hidden" name="lis_person_name_given" value="Siân"> 
<input type="hidden" name="lis_person_sourcedid" value="school.edu:user"> 
<input type="hidden" name="resource_link_description" value="This learning space is private"> 
<input type="hidden" name="resource_link_id" value="res-0012612"> 
<input type="hidden" name="resource_link_title" value="My Weekly Wiki"> 
<input type="hidden" name="roles" value="Instructor"> 
<input type="hidden" name="tool_consumer_info_product_family_code" value="sakai-unit"> 
<input type="hidden" name="tool_consumer_info_version" value="0.9"> 
<input type="hidden" name="tool_consumer_instance_description" value="University of School (LMSng)"> 
<input type="hidden" name="tool_consumer_instance_guid" value="lmsng.school.edu"> 
<input type="hidden" name="user_id" value="user-0016"> 
<input type="hidden" name="oauth_callback" value="about:blank"> 
<input type="hidden" name="custom_simple_key" value="custom_simple_value"> 
<input type="hidden" name="custom_complex____________key" value="[email protected]#$^*(){}[]½Value"> 
<input type="hidden" name="lti_version" value="LTI-1p0"> 
<input type="hidden" name="lti_message_type" value="basic-lti-launch-request"> 
<input type="hidden" name="oauth_version" value="1.0"> 
<input type="hidden" name="oauth_nonce" value="Z2WVNEPUZkzsolOe4hRvKbkXtOSmYiyw"> 
<input type="hidden" name="oauth_timestamp" value="1429793062"> 
<input type="hidden" name="oauth_consumer_key" value="feras"> 
<input type="hidden" name="oauth_signature_method" value="HMAC-SHA1"> 
<input type="hidden" name="oauth_signature" value="g908qTtVGh8MsOgVUdarVlSBmC0="> 
<input type="hidden" name="ext_submit" value="Finish Launch"> 
</form><iframe name="basicltiLaunchFrame" id="basicltiLaunchFrame" src="" width="100%" height="900" scrolling="auto" frameborder="1" transparency=""> 
</iframe> 
<script type="text/javascript"> 
    document.getElementById("ltiLaunchForm").style.display = "none"; 
    nei = document.createElement('input'); 
    nei.setAttribute('type', 'hidden'); 
    nei.setAttribute('name', 'ext_submit'); 
    nei.setAttribute('value', 'FinishLaunch'); 
    document.getElementById("ltiLaunchForm").appendChild(nei); 
    document.ltiLaunchForm.submit(); 
</script> 
</body> 
</html> 

然後調用從qtiworks

@RequestMapping(value="/domainlaunch", method=RequestMethod.POST) 
    public String ltiDomainLevelLaunch(final HttpSession httpSession, final HttpServletRequest request, 
      final HttpServletResponse response) 
      throws IOException { 
     /* Decode LTI launch request, and bail out on error */ 
     final DecodedLtiLaunch decodedLtiLaunch = ltiLaunchService.decodeLtiLaunchData(request, LtiLaunchType.DOMAIN); 
     if (decodedLtiLaunch.isError()) { 
      response.sendError(decodedLtiLaunch.getErrorCode(), decodedLtiLaunch.getErrorMessage()); 
      return null; 
     } 
     final LtiLaunchData ltiLaunchData = decodedLtiLaunch.getLtiLaunchData(); 

     /* Make sure this is a domain launch */ 
     final LtiUser ltiUser = decodedLtiLaunch.getLtiUser(); 
     final LtiDomain ltiDomain = ltiUser.getLtiDomain(); 
     if (ltiDomain==null) { 
      response.sendError(HttpServletResponse.SC_BAD_REQUEST, "The tool consumer has attempted a domain-level launch using a link-level key"); 
      return null; 
     } 

     /* Extract/create the corresponding LtiResource for this launch */ 
     final LtiResource ltiResource = ltiLaunchService.provideLtiResource(decodedLtiLaunch); /* (May be null for candidates) */ 
     final UserRole userRole = ltiUser.getUserRole(); 

     if (userRole==UserRole.INSTRUCTOR) { 
      /* If user is an instructor, we'll forward to the LTI instructor MVC after 
      * "authenticating" the user by creating and storing an LtiDomainTicket 
      * in the session */ 
      final LtiAuthenticationTicket ltiDomainTicket = new LtiAuthenticationTicket(ltiUser.getId(), ltiResource.getId(),ltiLaunchData.getLaunchPresentationReturnUrl()); 
      LtiResourceAuthenticationFilter.authenticateUserForResource(httpSession, ltiDomainTicket); 
      return "redirect:/lti/resource/" + ltiResource.getId(); 
     } 
     else if (userRole==UserRole.CANDIDATE) { 
      /* If user is a candidate, then we'll launch/reuse a candidate session */ 
      if (ltiResource==null) { 
       return "candidateLaunchError"; 
      } 

      /* Extract relevant data */ 
      final String returnUrl = ltiLaunchData.getLaunchPresentationReturnUrl(); 
      final String lisOutcomeServiceUrl = ltiLaunchData.getLisOutcomeServiceUrl(); 
      final String lisResultSourcedid = ltiLaunchData.getLisResultSourcedid(); 

      /* Launch and redirect to session */ 
      try { 
       final CandidateSessionTicket candidateSessionTicket = candidateSessionLaunchService.launchDomainLevelLtiCandidateSession(httpSession, 
         ltiUser, ltiResource, returnUrl, lisOutcomeServiceUrl, lisResultSourcedid); 
       return GlobalRouter.buildSessionStartRedirect(candidateSessionTicket); 
      } 
      catch (final CandidateException e) { 
       return "candidateLaunchError"; 
      } 
     } 
     else { 
      throw new QtiWorksLogicException("Unexpected LTI userRole " + userRole); 
     } 
    } 

問題是decodedLtiLaunch.isError()返回true dominlaunch並沒有執行我的要求。

我調試的問題,同時發現HttpServletRequest request在parameterMap的沒有項目

但是,它的工作很好,當請求來自Moodle的(要求的parameterMap的有通過PARAMS)

我怎麼能解決這個問題,請?

在此先感謝。

+0

什麼是錯誤?在黑暗中拍攝:我猜''oauth_signature'在這裏是有罪的。 – Bigood

回答

0

不知道你看到確切的錯誤代碼是,我要做出一個非常強大的猜測,你的簽名是壞

由於您使用的是Java,我建議你利用basiclti-UTIL庫這IMSGlobal提供生成簽名

添加以下依賴

<dependency> 
    <groupId>org.imsglobal</groupId> 
    <artifactId>basiclti-util</artifactId> 
    <version>1.1.2</version> 
</dependency> 

然後用下面的代碼生成簽名

Map<String, String> signedParameters = new LtiOauthSigner() 
    .signParameters(parameters, key, secret, url, "POST"); 

然後獲取signedParameters映射中的所有鍵值對,並使用它構造您的示例中的表單輸入標記。