3

I've created a LTI tool that I'm integrating with moodle. I have created a consumer key and secret but I'm unsure how do I validate (authenticate) the launch request.

Here is the raw request that I'm receiving, so I'm guessing I need to validate the oauth_signature to authenticate the request. I've come across some examples but I need the oauth token too, but it's not returned in the launch request.

I would really appreciate any help!

POST http://ltitest.cloudapp.net/launch HTTP/1.1
Host: ltitest.cloudapp.net
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://demo.moodle.net/mod/lti/launch.php?id=7
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 1296

oauth_version=1.0&oauth_nonce=d8e900f0b71e76c4b12e89681c9b5cb9&oauth_timestamp=1412987714&oauth_consumer_key=username&resource_link_id=1&resource_link_title=tool&resource_link_description=&user_id=2&roles=Instructor%2Curn%3Alti%3Asysrole%3Aims%2Flis%2FAdministrator&context_id=2&context_label=My+first+course&context_title=My+first+course&launch_presentation_locale=en&lis_result_sourcedid=%7B%22data%22%3A%7B%22instanceid%22%3A%221%22%2C%22userid%22%3A%222%22%2C%22launchid%22%3A449414780%7D%2C%22hash%22%3A%2226f6510ff6e91e1a7814805190c01a9e9d02575de135d7a1483a70626bae8782%22%7D&lis_outcome_service_url=http%3A%2F%2Fdemo.moodle.net%2Fmod%2Flti%2Fservice.php&lis_person_name_given=Admin&lis_person_name_family=User&lis_person_name_full=Admin+User&lis_person_contact_email_primary=demo%40moodle.a&ext_lms=moodle-2&tool_consumer_info_product_family_code=moodle&tool_consumer_info_version=2014051202&oauth_callback=about%3Ablank&lti_version=LTI-1p0&lti_message_type=basic-lti-launch-request&tool_consumer_instance_guid=demo.moodle.net&launch_presentation_return_url=http%3A%2F%2Fdemo.moodle.net%2Fmod%2Flti%2Freturn.php%3Fcourse%3D2%26launch_container%3D3%26instanceid%3D1&oauth_signature_method=HMAC-SHA1&oauth_signature=JmFLDbhi%2FstYEFTSNA%2F44biCQkM%3D&ext_submit=Press+to+launch+this+activity
4

2 回答 2

1

我不久前解决了这个问题,尽管它可能对任何寻求解决方案的人都派上用场。

首先获取 oauth 库:https ://www.nuget.org/packages/Microsoft.Owin.Security.OAuth/

// parse out the signature from the http req.
ProviderRequest providerRequest = new ProviderRequest();
providerRequest.ParseRequest(httpRequest, false);
String httpSig = providerRequest.Signature;

// now generate a new signature from our secret
String generatedSig = GenerateOAuthSignature(secret, req);

if( generatedSig == httpSig ){
   // valid oauth request
}

生成 OAuthSignature 是 owin 库的一部分,但代码的作用是:

    internal static string GenerateSignatureBase(string httpMethod, Uri url, NameValueCollection parameters)
    {
        var normalizedUrl = string.Format("{0}://{1}", url.Scheme, url.Host);
        if (!((url.Scheme == "http" && url.Port == 80) || (url.Scheme == "https" && url.Port == 443)))
        {
            normalizedUrl += ":" + url.Port;
        }
        normalizedUrl += url.AbsolutePath;

        StringBuilder signatureBase = new StringBuilder();
        signatureBase.Append(httpMethod.ToRfc3986EncodedString().ToUpper()).Append('&');
        signatureBase.Append(normalizedUrl.ToRfc3986EncodedString()).Append('&');

        var excludedNames = new List<string> { OAuthConstants.SignatureParameter };
        signatureBase.Append(parameters.ToNormalizedString(excludedNames).ToRfc3986EncodedString());

        return signatureBase.ToString();
    }

    /// <summary>
    /// Generates a signature using the specified signatureType 
    /// </summary>
    /// <param name="httpMethod">The http method used</param>
    /// <param name="url">The full url to be signed</param>
    /// <param name="parameters">The collection of parameters to sign</param>
    /// <param name="consumerSecret">The OAuth consumer secret used to generate the signature</param>
    /// <returns>A base64 string of the hash value</returns>
    public static string GenerateSignature(string httpMethod, Uri url, NameValueCollection parameters, string consumerSecret)
    {
        var signatureBase = GenerateSignatureBase(httpMethod, url, parameters);

        // Note that in LTI, the TokenSecret (second part of the key) is blank
        HMACSHA1 hmacsha1 = new HMACSHA1();
        hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&", consumerSecret.ToRfc3986EncodedString()));

        var dataBuffer = Encoding.ASCII.GetBytes(signatureBase);
        var hashBytes = hmacsha1.ComputeHash(dataBuffer);

        return Convert.ToBase64String(hashBytes);
    }
于 2015-07-15T11:32:46.003 回答
0

LTI 是由 IMS 全球学习联盟定义的一种通信协议,它允许将来自工具提供者 (TP) 的远程工具和内容安全地集成到工具消费者 (TC) 中。

与 OAuth 1.0 一样,通过对所有请求参数进行排序、添加使用者密钥、时间戳和随机数,并使用共享密钥将它们散列在一起,生成签名。您必须验证签名并为经过身份验证的请求调用请求的链接。

RFC 5849中,您可以找到相关的文档和示例。

token
         A unique identifier issued by the server and used by the client
         to associate authenticated requests with the resource owner
         whose authorization is requested or has been obtained by the
         client.  Tokens have a matching shared-secret that is used by
         the client to establish its ownership of the token, and its
         authority to represent the resource owner.

   The original community specification used a somewhat different
   terminology that maps to this specifications as follows (original
   community terms provided on left):

   Consumer:  client

   Service Provider:  server

   User:  resource owner

   Consumer Key and Secret:  client credentials

   Request Token and Secret:  temporary credentials

   Access Token and Secret:  token credentials

另请检查:验证启动

于 2014-11-17T12:06:29.400 回答