我创建了一个与moodle集成的LTI工具。我创建了一个消费者密钥和秘密,但我不确定如何验证(验证)启动请求。
以下是我收到的原始请求,因此我猜测我需要验证oauth_signature以验证请求。我已经遇到过一些示例,但我也需要oauth令牌,但它在启动请求中没有返回。
我真的很感激任何帮助!
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<i_version=LTI-1p0<i_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
答案 0 :(得分:0)
LTI是IMS全球学习联盟定义的通信协议,允许工具提供商(TP)的远程工具和内容安全地集成到工具消费者(TC)中。
与OAuth 1.0一样,生成签名,方法是对所有请求参数进行排序,添加使用者密钥,时间戳和nonce,并使用共享密钥将它们一起散列。您必须验证签名并为经过身份验证的请求调用请求的链接。
在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
同时检查:Validating launches。
答案 1 :(得分:0)
我在一段时间后解决了这个问题,虽然对于寻找解决方案的人来说它可能会派上用场。
首先获取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
}
生成OAuthSignature是owin lib的一部分,但是代码的作用是什么:
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);
}