in apps/samplecode/education/rosterapi/EducationAccelerator.WebApi/EducationAccelerator.WebApi/Middlewares/OAuth.cs [122:193]
public static int Verify(HttpContext context, ApiContext db)
{
var request = context.Request;
// Setup the variables necessary to recreate the OAuth 1.0 signature
string httpMethod = request.Method.ToUpper();
var url = SignatureBaseStringUri(request);
// Collect header and querystring params
// OneRoster endpoints don't support urlencoded body
var headerParams = getHeaderParams(request);
var queryParams = getQueryParams(request);
var combinedParams = headerParams.Concat(queryParams).ToList();
// Generate and accept or reject the signature
try
{
// if bearer token is used, then other fields are unnecessary
var token = combinedParams.FirstOrDefault(kvp => kvp.Key == "Bearer").Value;
if (VerifyBearerToken(token, db))
{
return 0;
}
var nonce = combinedParams.First(kvp => kvp.Key == "oauth_nonce").Value;
var timestamp = combinedParams.First(kvp => kvp.Key == "oauth_timestamp").Value;
var clientSignature = combinedParams.First(kvp => kvp.Key == "oauth_signature").Value;
var signatureMethod = combinedParams.First(kvp => kvp.Key == "oauth_signature_method").Value.ToUpper();
var clientId = combinedParams.First(kvp => kvp.Key == "oauth_consumer_key").Value;
if (!IsValidTimestamp(timestamp))
{
Trace.TraceError($"Bad timestamp: {timestamp}");
return 401;
}
if (!LatchNonce(nonce, db))
{
Trace.TraceError($"Bad nonce: {nonce}");
return 401;
}
if (clientId != OAUTH_CONSUMER_KEY)
{
Trace.TraceError($"Bad consumer key");
return 401;
}
var normalizedParams = NormalizeParams(combinedParams);
var signatureBaseString = $"{httpMethod}&{url}&{normalizedParams}";
if (signatureMethod != "HMAC-SHA1" &&
signatureMethod != "HMAC-SHA2" &&
signatureMethod != "HMAC-SHA256")
{
Trace.TraceError($"Bad signing method: {signatureMethod}");
return 400;
}
var hmac = GenerateHmac(signatureBaseString, signatureMethod, OAUTH_CONSUMER_SECRET);
if (hmac != clientSignature)
{
Trace.TraceError($"Signature mismatch: {hmac} | {clientSignature}, signatureBaseString is {signatureBaseString}");
return 401;
}
return 0;
}
catch(InvalidOperationException)
{
return 400;
}
}