/// <summary> /// Signs the request appropriately to make it an authenticated request. /// Note that this method takes the URI components as decoding the URI components requires the knowledge /// of whether the URI is in path-style or host-style and a host-suffix if it's host-style. /// </summary> public void SignRequest(HttpWebRequest request, ResourceUriComponents uriComponents) { if (request == null) { throw new ArgumentNullException("request"); } string message = MessageCanonicalizer.CanonicalizeHttpRequest(request, uriComponents); string computedBase64Signature = ComputeMacSha(message); request.Headers.Add(HeaderNames.Authorization, string.Format(CultureInfo.InvariantCulture, "{0} {1}:{2}", AuthenticationSchemeNames.SharedKeyAuthSchemeName, accountName, computedBase64Signature)); }
public void SignRequestForSharedKeyLite(HttpWebRequest request, ResourceUriComponents uriComponents) { if (request == null) { throw new ArgumentNullException("request"); } // add the date header to the request string dateString = MessageCanonicalizer.ConvertDateTimeToHttpString(DateTime.UtcNow); request.Headers.Add(HeaderNames.StorageDateTime, dateString); // compute the signature and add the authentication scheme string message = MessageCanonicalizer.CanonicalizeHttpRequestForSharedKeyLite(request, uriComponents, dateString); string computedBase64Signature = ComputeMacSha(message); request.Headers.Add(HeaderNames.Authorization, string.Format(CultureInfo.InvariantCulture, "{0} {1}:{2}", AuthenticationSchemeNames.SharedKeyLiteAuthSchemeName, accountName, computedBase64Signature)); }
/// <summary> /// Constructs a path-style resource URI given all its constituents /// </summary> private static Uri ConstructPathStyleResourceUri(Uri endpoint, ResourceUriComponents uriComponents) { StringBuilder path = new StringBuilder(string.Empty); if (uriComponents.AccountName != null) { path.Append(uriComponents.AccountName); if (uriComponents.ContainerName != null) { path.Append(ConstChars.Slash); path.Append(uriComponents.ContainerName); if (uriComponents.RemainingPart != null) { path.Append(ConstChars.Slash); path.Append(uriComponents.RemainingPart); } } } return(ConstructUriFromUriAndString(endpoint, path.ToString())); }
/// <summary> /// Constructs an URI given all its constituents /// </summary> /// <param name="endpoint"> /// This is the service endpoint in case of path-style URIs and a host suffix in case of host-style URIs /// IMPORTANT: This does NOT include the service name or account name /// </param> /// <param name="uriComponents">Uri constituents</param> /// <param name="pathStyleUri">Indicates whether to construct a path-style Uri (true) or host-style URI (false)</param> /// <returns>Full uri</returns> public static Uri ConstructResourceUri(Uri endpoint, ResourceUriComponents uriComponents, bool pathStyleUri) { return(pathStyleUri ? ConstructPathStyleResourceUri(endpoint, uriComponents) : ConstructHostStyleResourceUri(endpoint, uriComponents)); }
internal static string CanonicalizeHttpRequestForSharedKeyLite(HttpWebRequest request, ResourceUriComponents uriComponents, string date) { StringBuilder canonicalizedString = new StringBuilder(date); AppendStringToCanonicalizedString(canonicalizedString, MessageCanonicalizer.GetCanonicalizedResource(request.Address, uriComponents)); return(canonicalizedString.ToString()); }
/// <summary> /// Canonicalize HTTP header contents. /// </summary> /// <param name="request">An HttpWebRequest object.</param> /// <param name="uriComponents">Components of the Uri extracted out of the request.</param> /// <returns>The canonicalized string of the given HTTP request's header.</returns> internal static string CanonicalizeHttpRequest(HttpWebRequest request, ResourceUriComponents uriComponents) { return(CanonicalizeHttpRequest( request.Address, uriComponents, request.Method, request.ContentType, string.Empty, request.Headers)); }
internal static string CanonicalizeHttpRequest( Uri address, ResourceUriComponents uriComponents, string method, string contentType, string date, NameValueCollection headers) { // The first element should be the Method of the request. // I.e. GET, POST, PUT, or HEAD. CanonicalizedString canonicalizedString = new CanonicalizedString(method); // The second element should be the MD5 value. // This is optional and may be empty. string httpContentMD5Value = string.Empty; // First extract all the content MD5 values from the header. ArrayList httpContentMD5Values = HttpRequestAccessor.GetHeaderValues(headers, HeaderNames.ContentMD5); // If we only have one, then set it to the value we want to append to the canonicalized string. if (httpContentMD5Values.Count == 1) { httpContentMD5Value = (string)httpContentMD5Values[0]; } canonicalizedString.AppendCanonicalizedElement(httpContentMD5Value); // The third element should be the content type. canonicalizedString.AppendCanonicalizedElement(contentType); // The fourth element should be the request date. // See if there's an storage date header. // If there's one, then don't use the date header. ArrayList httpStorageDateValues = HttpRequestAccessor.GetHeaderValues(headers, HeaderNames.StorageDateTime); if (httpStorageDateValues.Count > 0) { date = null; } canonicalizedString.AppendCanonicalizedElement(date); // Look for header names that start with StorageHttpConstants.HeaderNames.PrefixForStorageHeader // Then sort them in case-insensitive manner. ArrayList httpStorageHeaderNameArray = new ArrayList(); foreach (string key in headers.Keys) { if (key.ToLowerInvariant().StartsWith(HeaderNames.PrefixForStorageHeader, StringComparison.Ordinal)) { httpStorageHeaderNameArray.Add(key.ToLowerInvariant()); } } httpStorageHeaderNameArray.Sort(); // Now go through each header's values in the sorted order and append them to the canonicalized string. foreach (string key in httpStorageHeaderNameArray) { StringBuilder canonicalizedElement = new StringBuilder(key); string delimiter = ":"; ArrayList values = HttpRequestAccessor.GetHeaderValues(headers, key); // Go through values, unfold them, and then append them to the canonicalized element string. foreach (string value in values) { // Unfolding is simply removal of CRLF. string unfoldedValue = value.Replace(ConstChars.CarriageReturnLinefeed, string.Empty); // Append it to the canonicalized element string. canonicalizedElement.Append(delimiter); canonicalizedElement.Append(unfoldedValue); delimiter = ","; } // Now, add this canonicalized element to the canonicalized header string. canonicalizedString.AppendCanonicalizedElement(canonicalizedElement.ToString()); } // Now we append the canonicalized resource element. string canonicalizedResource = GetCanonicalizedResource(address, uriComponents); canonicalizedString.AppendCanonicalizedElement(canonicalizedResource); return(canonicalizedString.Value); }