/// <summary> /// Perform validation using all QS or form params and load /// APIKEY etc from the headers collection. /// Check this class next year.. /// </summary> /// <param name="request"></param> /// <param name="allowedHttpMethods"></param> /// <returns></returns> public static RESTAuthenticator AuthenticateByHeaders(HttpRequest request, string[] allowedHttpMethods) { RESTAuthenticator auth = new RESTAuthenticator(); string xApiKey = request.Headers["X-ApiKey"]; string xTimestamp = request.Headers["X-Timestamp"]; string xSignature = request.Headers["X-Signature"]; if (String.IsNullOrEmpty(xSignature) || String.IsNullOrEmpty(xApiKey) || String.IsNullOrEmpty(xTimestamp)) { auth._message = "Bad Request"; auth._statusCode = HttpStatusCode.BadRequest; return auth; } if (!isAllowedHttpMethod(request.HttpMethod, allowedHttpMethods)) { auth._message = "Method Not Allowed"; auth._statusCode = HttpStatusCode.MethodNotAllowed; return auth; } #region Validate Timestamp // Get timestamp as DateTime and validate: DateTime remoteTimestamp = new DateTime(1970, 1, 1, 1, 1, 1, DateTimeKind.Utc); DateTime.TryParse(xTimestamp, out remoteTimestamp); if (!isValidTimestamp(remoteTimestamp.ToUniversalTime(), 60 * 15)) { // Expired timestamp parameter. auth._message = "Timestamp invalid or expired"; auth._statusCode = HttpStatusCode.BadRequest; return auth; } #endregion // Check if the API KEY and secret are OK String secret = GetSecretKey(xApiKey); if (String.IsNullOrEmpty(secret)) { auth._message = "Invalid API key: " + xApiKey; auth._statusCode = HttpStatusCode.BadRequest; return auth; } if (! isValidResourceSignature(request, secret, xSignature)) { auth._message = "Invalid signature"; auth._statusCode = HttpStatusCode.BadRequest; return auth; } // Passed all tests auth._message = "OK"; auth._statusCode = HttpStatusCode.OK; return auth; }
/// <summary> /// Authenticates a Request and returns the status object. /// </summary> /// <param name="request">The request from which to get parameters.</param> /// <param name="allowedHttpMethods">The valid methods for this operation. Array can contain DELETE, GET, HEAD, PUT, POST</param> /// <param name="reqParams">An array of parameter names that must exist in the request.</param> /// <param name="apiKeyParamName">The name of the parameter that contains the Account identifier.</param> /// <param name="signatureParamName">The name of the parameter that contains the signed request.</param> /// <param name="timestampParamName">The name of the parameter that contains the timestamp in UTC format</param> /// <returns></returns> public static RESTAuthenticator AuthenticateRequest(HttpRequest request, string[] allowedHttpMethods, string[] reqParams, string apiKeyParamName, string signatureParamName, string timestampParamName) { RESTAuthenticator auth = new RESTAuthenticator(); #region Validate Timestamp // Validate Timestamp // TODO Refactor this check to validate against Pragmatic paradigm // Exit if request missing timestamp param if (String.IsNullOrEmpty(request[timestampParamName])) { // Missing timestamp parameter. auth._message = "Missing Timestamp parameter"; auth._statusCode = HttpStatusCode.BadRequest; return auth; } // Validate Timestamp // Has timestamp parameter. // Get timestamp as DateTime and validate: DateTime remoteTimestamp = new DateTime(1970, 1, 1, 1, 1, 1, DateTimeKind.Utc); DateTime.TryParse(request[timestampParamName], out remoteTimestamp); if (!isValidTimestamp(remoteTimestamp.ToUniversalTime(), 60 * 15)) { // Expired timestamp parameter. auth._message = "Timestamp invalid or expired"; auth._statusCode = HttpStatusCode.BadRequest; return auth; } #endregion #region Validate HTTPMethod // Validate HTTPMethod if ( !isAllowedHttpMethod(request.HttpMethod, allowedHttpMethods) ) { auth._message = "Method Not Allowed"; auth._statusCode = HttpStatusCode.MethodNotAllowed; return auth; } #endregion #region Validate parameters if (missingRequiredParams(request, reqParams)) { // Missing required parameter. auth._message = "Missing required parameters"; auth._statusCode = HttpStatusCode.BadRequest; return auth; } #endregion #region Validate signature string secretKey = GetSecretKey(request[apiKeyParamName]); string signature = request[signatureParamName]; if (!isValidSignature(request, secretKey, signature, reqParams)) { auth._message = "Invalid signature"; auth._statusCode = HttpStatusCode.BadRequest; return auth; } #endregion // If all tests passed set and return OK response auth._message = "OK"; auth._statusCode = HttpStatusCode.OK; return auth; }