gpt4 book ai didi

java - 无法为我的 IMS LTI 请求生成 oauth_signature

转载 作者:行者123 更新时间:2023-11-30 06:58:00 36 4
gpt4 key购买 nike

在 IMS 模拟器 ( http://ltiapps.net/test/tc.php ) 中,单击“保存数据”时,将使用自动填充的数据生成 outh_signature 并将其作为隐藏值以 frmLaunch(name='frmLaunch') 形式放入。我需要以编程方式生成类似的 outh_signature,但即使我使用相同的 oauth_nounce 和 oauth_timestamp ,我也无法生成模拟器生成的确切 oauth_signature 。我不确定生成时需要发送的请求正文是什么签名..

要重新创建场景,请按照以下步骤操作

  1. 点击网址http://ltiapps.net/test/tc.php
  2. 点击“清除数据”,然后在弹出窗口中点击“确定”
  3. 选择角色“学习者”并点击“保存数据”
  4. 保存数据后,您将看到一个 outh_signature 隐藏值,其输入 ID 为“oauth_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= 但预期是 yuuvR1pVDm5xWOYhMtBcBBVTdf8=

版本=LTI-1p0&重置=&端点= http://ltiapps.net/test/tp.php&register=http://ltiapps.net/test/tp.php&key=jisc.ac.uk&secret=secret&lti_message_type=basic-lti-launch-request&message_type=&tool=&lti_version=LTI-1p0&launch_presentation_locale=&launch_presentation_document_target=&launch_presentation_width=&launch_presentation_height=&launch_presentation_css_url=&launch_presentation_return_url=&custom=&ext=&signaturemethod=HMAC-SHA1&accept_media_types=&accept_presentation_document_targets=embed,frame,iframe,window,popup,overlay,none&content_item_return_url=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_consumer_info_version=&context_id=&context_type=&a_context_type=&context_title=&context_label=&lis_course_offering_sourcedid=&lis_course_section_sourcedid=&resource_link_id=429785226&resource_link_title=&resource_link_description=&user_id=&lis_person_name_given=&lis_person_name_family=&lis_person_name_full=&lis_person_contact_email_primary=&lis_person_sourcedid=&roles=Learner&a_role=&user_image=&mentors=&username=&lis_outcome_service_url=&lis_result_sourcedid=&ext_ims_lis_basic_outcome_url=&ext_ims_lis_resultvalue_sourcedids=&ext_ims_lis_memberships_url=&ext_ims_lis_memberships_id=&ext_ims_lti_tool_setting_url=&ext_ims_lti_tool_setting_id=&setting=&custom_tc_profile_url=&custom_system_setting_url=&custom_context_setting_url=&custom_link_setting_url=&custom_lineitems_url=&custom_results_url=&custom_lineitem_url=&custom_result_url=&custom_context_memberships_url=&custom_link_memberships_url=&custom_caliper_federated_session_id=&custom_caliper_eventstore_url=&custom_caliper_api_key=

你能告诉我我哪里出了问题吗?

最佳答案

由于您使用的是 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 启动 validator ,以便与 Spring-web 轻松集成。

工具使用者:

  • 创建有效的 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");

关于java - 无法为我的 IMS LTI 请求生成 oauth_signature,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41451019/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com