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
Bigood
  • 9,457
  • 3
  • 36
  • 65
webber
  • 1,523
  • 4
  • 21
  • 46

2 Answers2

1

I solved this a while back and though it might come in handy for anyone looking for a solution.

Start by getting the oauth lib: 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
}

Generate OAuthSignature is part of the owin lib, but there what the code does:

    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);
    }
webber
  • 1,523
  • 4
  • 21
  • 46
0

LTI is a communication protocol defined by IMS Global Learning Consortium that allows remote tools and content from Tool Providers (TP) to be securely integrated into a Tool Consumer (TC).

The signature is generated, as with OAuth 1.0, by sorting all the request parameters, adding the consumer key, a timestamp and a nonce, and hashing them together using the shared secret. You have to validate the signature and invoke the requested link for authenticated request.

In RFC 5849, you can find the related documentation and examples for this.

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

Also check this: Validating launches.

Sarah Elan
  • 2,313
  • 1
  • 21
  • 42
Aditya
  • 2,665
  • 4
  • 32
  • 28