无法为我的ims lti请求生成oauth\u签名

niwlg2el  于 2021-07-12  发布在  Java
关注(0)|答案(1)|浏览(447)

在ims模拟器中(http://ltiapps.net/test/tc.php)单击“save data”(保存数据)时,自动填充的数据将生成outh\ U签名,并以frmlaunch(name='frmlaunch')形式作为隐藏值放入。我需要通过编程生成类似的outh\u签名,但是我无法生成仿真器生成的确切oauth\u签名,即使我使用相同的oauth\u名称和oauth\u时间戳。。我不确定生成签名时需要发送的请求主体是什么。。
要重新创建场景,请执行以下步骤
点击网址http://ltiapps.net/test/tc.php
单击清除数据,然后单击弹出窗口中的确定
选择角色作为学习者,然后单击保存数据
保存数据后,您将看到一个outh\u signature隐藏值,输入id为“oauth\u signature”
我试图以下面的方式生成,但未能获得预期的签名。

import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.HttpsURLConnection;

// Apache Commons Libraries used for the Nonce & Base64
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;

public class OAuthTest {

  public static void main(final String[] args) throws Exception
  {
    // Setup the variables necessary to create the OAuth 1.0 signature and   make the request
    String httpMethod  = "POST";
    String consumerKey = "jisc.ac.uk";
    String secret      = "secret";  
   String signatureMethod = "HMAC-SHA1";
    String body = ""; //mentioned in the description
    byte[] requestBody = null;

URL url = new URL("http://ltiapps.net/test/tp.php");

// Set the Nonce and Timestamp parameters
String nonce = "6d95eef168e568a530d1cd419a997952";//getNonce();
String timestamp = "1483470400";//getTimestamp();

System.out.println("Nonce:" + getNonce());
System.out.println("timestamp:" + getTimestamp());

// Set the request body if making a POST or PUT request
if ("POST".equals(httpMethod)  || "PUT".equals(httpMethod))
{
  requestBody = body.getBytes("UTF-8");
}

// Create the OAuth parameter name/value pair
Map<String, String> oauthParams = new LinkedHashMap<String, String>();
oauthParams.put("oauth_consumer_key", consumerKey);
oauthParams.put("oauth_signature_method", signatureMethod);
oauthParams.put("oauth_timestamp", timestamp);
oauthParams.put("oauth_nonce", nonce);

// Get the OAuth 1.0 Signature
String signature = generateSignature(httpMethod, url, oauthParams, requestBody, secret);
System.out.println(String.format("OAuth 1.0 Signature: %s", signature));

}

private static String getNonce()
{
    return RandomStringUtils.randomAlphanumeric(32);
}

private static String getTimestamp()
{    
    return Long.toString((System.currentTimeMillis() / 1000));
 }

 private static String generateSignature(

String httpMethod,
  URL url,
  Map<String, String> oauthParams,
  byte[] requestBody,
  String secret
 )   throws UnsupportedEncodingException
  {
// Ensure the HTTP Method is upper-cased
httpMethod = httpMethod.toUpperCase();

// Construct the URL-encoded OAuth parameter portion of the signature base string
String encodedParams = normalizeParams(httpMethod, url, oauthParams, requestBody);

// URL-encode the relative URL
String encodedUri = URLEncoder.encode(url.getPath(), "UTF-8");

// Build the signature base string to be signed with the Consumer Secret
String baseString = String.format("%s&%s&%s", httpMethod, encodedUri, encodedParams);

    return hmacSha1(baseString, secret);
  }

  private static String normalizeParams(
      String httpMethod,
      URL url,
      Map<String, String> oauthParams,
      byte[] requestBody
  ) throws UnsupportedEncodingException
  {

    // Sort the parameters in lexicographical order, 1st by Key then by Value
    Map<String, String> kvpParams = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
    kvpParams.putAll(oauthParams); 

    // Place any query string parameters into a key value pair using equals ("=") to mark
    // the key/value relationship and join each parameter with an ampersand ("&")
    if (url.getQuery() != null)
    {
      for(String keyValue : url.getQuery().split("&"))
      {
        String[] p = keyValue.split("=");
        kvpParams.put(p[0],p[1]);
      }

    }

    // Include the body parameter if dealing with a POST or PUT request
    if ("POST".equals(httpMethod) || "PUT".equals(httpMethod))
    {
      String body = Base64.encodeBase64String(requestBody).replaceAll("\r\n", "");
      // url encode the body 2 times now before combining other params
      body = URLEncoder.encode(body, "UTF-8");
      body = URLEncoder.encode(body, "UTF-8");
      kvpParams.put("body", body);    
    }

    // separate the key and values with a "="
    // separate the kvp with a "&"
    StringBuilder combinedParams = new StringBuilder();
    String delimiter="";
    for(String key : kvpParams.keySet()) {
      combinedParams.append(delimiter);
      combinedParams.append(key);
      combinedParams.append("=");
      combinedParams.append(kvpParams.get(key));
      delimiter="&";
    }

    // url encode the entire string again before returning
    return URLEncoder.encode(combinedParams.toString(), "UTF-8");
  }

  public static String hmacSha1(String value, String key) {
        String algorithm = "HmacSHA1";
      try {
          // Get an hmac_sha1 key from the raw key bytes
          byte[] keyBytes = key.getBytes();           
          SecretKeySpec signingKey = new SecretKeySpec(keyBytes, algorithm);

          // Get an hmac_sha1 Mac instance and initialize with the signing key
          Mac mac = Mac.getInstance(algorithm);
          mac.init(signingKey);

          // Compute the hmac on input data bytes
         // byte[] rawHmac = mac.doFinal(value.getBytes());

          // Convert raw bytes to Hex
         // byte[] hexBytes = new Hex().encode(rawHmac);
          return new String(Base64.encodeBase64(mac.doFinal(value.getBytes()))).trim();
          //  Covert array of Hex bytes to a String
          //return new String(hexBytes, "UTF-8");
      } catch (Exception e) {
          throw new RuntimeException(e);
      }
  }
 }

pom.xml文件

<dependencies>
   <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.10</version>
    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.0</version>
    </dependency>

我通过如下发送请求正文尝试了上述程序,获得了oauth签名0yi3mbg7gmnwaz8yyisg4iohvq4=但预期是yuuvr1pvdm5xwoyhmtbcbvtdf8=
版本=lti-1p0&reset=端点(&E)=http://ltiapps.net/test/tp.php&register=http用法:/ltiapps.net/test/tp.php&key=jisc.ac.uk&secret=secret&lti\u message\u type=basic lti launch request&message\u type=&tool=&lti\u version=lti-1p0&launch\u presentation\u locale=&launch\u presentation\u document\u target=&launch\u presentation\u width=&launch\u presentation\u css\u url=&launch\u presentation\u return\u url=&custom=&ext=&signaturemethod=hmac-sha1&accept\u media\u types=&accept\u presentation\u document\u targets=embed,frame,iframe,window,popup,overlay,无内容\u项目\u返回\u url(&C)=http://ltiapps.net/test/tc-content.php&accept_unsigned=&accept_multiple=&accept_copy_advice=&auto_create=&title=&text=&data=&tool_consumer_instance_guid=&tool_consumer_instance_name=&tool_consumer_instance_description=&tool_consumer_instance_url=&tool_consumer_instance_contact_email=&tool_consumer_info_product_family_code=&tool\u consumer\u info\u version=&context\u id=&context\u type=&a\u context\u type=&context\u title=&context\u label=&lis\u course\u offering\u sourcedid=&lis\u course\u section\u sourcedid=&resource\u link\u id=429785226&resource\u link\u title=&resource\u link\u description=&user\u id=&lis\u person\u name\u given=&lis\u person\u name\u family=&lis\u person\u name\u full=&lis\u person\u contact\u email\u primary=&lis\u person\u sourcedid=&roles=learner&a\u role=&user\u image=&mentors=&username=&lis\u outcome\u service\u url=&lis\u result\u sourcedid=&ext\u ims\u lis\u basic\u outcome\u url=&ext\u ims\u resultvalue\u sourcedids=&ext\u ims\u lis\u memberships\u url=&ext\u ims\u lis\u memberships\u id=&ext\u ims\u lti\u tool\u setting\u id=&setting=&custom\u tc\u profile\u url=&custom\u系统\设置\ url=&自定义\上下文\设置\ url=&自定义\链接\设置\ url=&自定义\行项目\ url=&自定义\结果\ url=&自定义\行项目\ url=&自定义\结果\ url=&自定义\上下文\成员身份\ url=&自定义\链接\成员身份\ url=&自定义\联合\会话\ id=&自定义\事件存储\ url=&自定义\ api \密钥=
你能告诉我哪里出了问题吗。。

11dmarpk

11dmarpk1#

既然您使用的是java,我建议您使用imsglobal提供的basiclti util库,它会处理您正在做的大部分工作,并且不需要您重新发明轮子
将以下依赖项添加到pom

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

此库支持:
工具提供商:
验证lti启动请求
发送lti 1.1结果请求(基于xml)
aspectj启动验证器,以便与SpringWeb轻松集成。
工具使用者:
创建有效的lti启动请求
验证工具使用者发送的lti启动请求

HttpServletRequest request; // java servlet request
LtiVerifier ltiVerifier = new LtiOauthVerifier();
String key = request.getParameter("oauth_consumer_key");
String secret = // retrieve corresponding secret for key from db
LtiVerificationResult ltiResult = ltiVerifier.verify(request, secret);

如果您试图签署一个传出请求,请使用以下命令

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

相关问题