/** * Gets the canonicalized data of the given request. * * <p> * The canonicalized data contains the list of fields separate with a tab '\t': * </p> * * <ol> * <li> * the request method (GET/PUT etc.) in upper case; * </li> * <li> * the scheme (http/https) in lower case; * </li> * <li> * the host from the Host header in lower case; * </li> * <li> * the relative URL that contains the path and query portions of the URL, * as it appears in the HTTP request line, see {@link #canonicalizeUri}; * </li> * <li> * the canonicalized request headers, see {@link #canonicalizeHeaders}; * </li> * <li> * the content hash of the request body for POST requests, see {@link #getContentHash}. * </li> * </ol> * * @param request the request. * @return the canonicalized data, and the possibly updated request. * @throws RequestSigningException */ private CanonicalizerHelper GetCanonicalizedRequest(HttpRequestMessage request) { StringBuilder sb = new StringBuilder(); string method = request.Method.Method; if (string.IsNullOrEmpty(method)) { throw new RequestSigningException("Invalid request: empty request method"); } sb.Append(method.ToUpper()); sb.Append('\t'); Uri uri = request.RequestUri; string scheme = uri.Scheme; if (string.IsNullOrEmpty(scheme)) { throw new RequestSigningException("Invalid request: empty request scheme"); } sb.Append(scheme.ToLower()); sb.Append('\t'); string host = GetHost(request); if (string.IsNullOrEmpty(host)) { throw new RequestSigningException("Invalid request: empty host"); } sb.Append(host.ToLower()); sb.Append('\t'); string rawRelativeUrl = request.RequestUri.PathAndQuery; string relativeUrl = CanonicalizeUri(rawRelativeUrl); sb.Append(relativeUrl); sb.Append('\t'); string canonicalizedHeaders = CanonicalizeHeaders(request); sb.Append(canonicalizedHeaders); sb.Append('\t'); CanonicalizerHelper contentHashResult = GetContentHash(request); string contentHash = contentHashResult.CanonicalizedData; sb.Append(contentHash); sb.Append('\t'); string data = sb.ToString(); return(new CanonicalizerHelper(data, contentHashResult.Request)); }
/** * Signs the given request with the given client credential. * * @param request the request to sign. * @param credential the credential used in the signing. * @return the signed request. * @throws RequestSigningException */ public HttpRequestMessage Sign(HttpRequestMessage request, IClientCredential credential) { string timeStamp = GetTimeStamp(DateTime.UtcNow); StringBuilder sb = new StringBuilder(); sb.Append(Algorithm); sb.Append(' '); sb.Append(AuthClientTokenName); sb.Append('='); sb.Append(credential.ClientToken); sb.Append(';'); sb.Append(AuthAccessTokenName); sb.Append('='); sb.Append(credential.AccessToken); sb.Append(';'); sb.Append(AuthTimestampName); sb.Append('='); sb.Append(timeStamp); sb.Append(';'); string nonce = Guid.NewGuid().ToString(); sb.Append(AuthNonceName); sb.Append('='); sb.Append(nonce); sb.Append(';'); string authData = sb.ToString(); try { string clientSecret = credential.ClientSecret; byte[] signingKeyBytes = Sign(timeStamp, Encoding.GetEncoding(Charset).GetBytes(clientSecret), HmacAlg); string signingKey = Convert.ToBase64String(signingKeyBytes); CanonicalizerHelper requestResult = GetCanonicalizedRequest(request); HttpRequestMessage updatedRequest = requestResult.Request; string requestData = requestResult.CanonicalizedData; StringBuilder signData = new StringBuilder(requestData); signData.Append(authData); string stringToSign = signData.ToString(); //if (LOGGER.isDebugEnabled()) { // LOGGER.debug(String.format("String to sign : '%s'", stringToSign)); //} byte[] signatureBytes = Sign(stringToSign, Encoding.GetEncoding(Charset).GetBytes(signingKey), HmacAlg); string signature = Convert.ToBase64String(signatureBytes); //if (LOGGER.isDebugEnabled()) { // LOGGER.debug(String.format("Signature : '%s'", signature)); //} // add the signature sb.Append(AuthSignatureName); sb.Append('='); sb.Append(signature); String authHeader = sb.ToString(); updatedRequest.Headers.Add("Authorization", authHeader); return(updatedRequest); } catch (Exception e) { throw new RequestSigningException("Failed to sign: invalid string encoding", e); } }