private string GetAuthenticationHeader(RestSharp.IRestClient client, RestSharp.IRestRequest request) { string requestContentBase64String = string.Empty; //Calculate UNIX time DateTime epochStart = new DateTime(1970, 01, 01, 0, 0, 0, 0, DateTimeKind.Utc); TimeSpan timeSpan = DateTime.UtcNow - epochStart; string requestTimeStamp = Convert.ToUInt64(timeSpan.TotalSeconds).ToString(); //create random nonce for each request string nonce = Guid.NewGuid().ToString("N"); // URLEncode the request URI var requestUri = HttpUtility.UrlEncode(client.BuildUri(request).AbsoluteUri.ToLower()); //Creating the raw signature string string signatureRawData = String.Format("{0}{1}{2}{3}{4}{5}", _srApiKey, request.Method, requestUri, requestTimeStamp, nonce, requestContentBase64String); var secretKeyByteArray = Convert.FromBase64String(_srApiSecret); byte[] signature = Encoding.UTF8.GetBytes(signatureRawData); using (HMACSHA256 hmac = new HMACSHA256(secretKeyByteArray)) { byte[] signatureBytes = hmac.ComputeHash(signature); string requestSignatureBase64String = Convert.ToBase64String(signatureBytes); //Setting the values in the Authorization header using custom scheme (amx) return("amx " + string.Format("{0}:{1}:{2}:{3}", _srApiKey, requestSignatureBase64String, nonce, requestTimeStamp)); } }
public Data.RestResponse Execute(string baseAddress, Data.RestRequest requestDetails) { this.BaseUrlString = baseAddress; RestSharp.IRestClient client = this.Client; // We're using RestSharp to execute HTTP requests. RestSharp copes with trailing "/" // on BaseUrl and leading "/" on Resource, whether one or both of the "/" are present // or absent. ValidateRequest(client, requestDetails); if (requestDetails.TransactionId == null) { requestDetails.TransactionId = Convert.ToInt64(DateTimeHelper.CurrentUnixTimeMillis()); } client.FollowRedirects = requestDetails.FollowRedirect; RestSharp.RestRequest request = BuildRequest(requestDetails); if (LOG.IsDebugEnabled) { try { LOG.Info("Http Request : {0} {1}", request.Method, client.BuildUri(request).AbsoluteUri); } catch (Exception e) { LOG.Error(e, "Exception in debug : {0}", e.Message); } // Request Header LogRequestHeaders(request); // Request Body if (IsEntityEnclosingMethod(request.Method)) { try { Parameter body = request.Parameters .Where(p => p.Type == ParameterType.RequestBody).FirstOrDefault(); LOG.Debug("Http Request Body : {0}", body.Value); } catch (IOException e) { LOG.Error(e, "Error in reading request body in debug : {0}", e.Message); } } } // Prepare Response Data.RestResponse responseDetails = new Data.RestResponse(); responseDetails.TransactionId = requestDetails.TransactionId; responseDetails.Resource = requestDetails.Resource; try { IRestResponse response = client.Execute(request); foreach (RestSharp.Parameter responseHeader in response.Headers) { responseDetails.addHeader(responseHeader.Name, responseHeader.Value.ToString()); } responseDetails.StatusCode = (int)response.StatusCode; responseDetails.StatusText = response.StatusDescription; // The Java byte data type is actually a signed byte, equivalent to sbyte in .NET. // Data.RestResponse is a direct port of the Java class so it uses // the sbyte data type. The strange conversion from byte[] to sbyte[] was from // the answer to Stackoverflow question http://stackoverflow.com/questions/25759878/convert-byte-to-sbyte // TODO: Check RestFixture code to see whether Data.RestResponse.RawBody can be converted to byte[]. responseDetails.RawBody = response.RawBytes; // Debug if (LOG.IsDebugEnabled) { // Not necessarily the same as the request URI. The response URI is the URI // that finally responds to the request, after any redirects. LOG.Debug("Http Request Path : {0}", response.ResponseUri); LogRequestHeaders(request); // Apache HttpClient.HttpMethod.getStatusLine() returns the HTTP response // status line. Can't do this with RestSharp as it cannot retrieve the // protocol version which is at the start of the status line. So just log // the status code and description. // Looks like they added ProtocolVersion to RestSharp in issue 795 (commit // 52c18a8) but it's only available in the FRAMEWORK builds. LOG.Debug("Http Response Status : {0} {1}", (int)response.StatusCode, response.StatusDescription); LOG.Debug("Http Response Body : {0}", response.Content); } if (IsResponseError(response)) { LOG.Error(response.ErrorException, response.ErrorMessage); string message = "Http call failed"; if (!string.IsNullOrWhiteSpace(response.ErrorMessage)) { message = response.ErrorMessage.Trim(); } throw new System.InvalidOperationException(message, response.ErrorException); } } catch (Exception e) { string message = "Http call failed"; throw new System.InvalidOperationException(message, e); } LOG.Debug("response: {0}", responseDetails); return(responseDetails); }