public static UriBuilder GetRedirectUriBuilder(string method, string scheme, CloudStorageAccount account, string containerName, string blobName, bool useSas, string queryString, bool decodeQueryParams = true) { CloudBlobContainer container = NamespaceHandler.GetContainerByName(account, containerName); // Strip any existing SAS query params as we'll replace them with our own SAS calculation var queryParams = RequestQueryParameters.Create(queryString, decodeQueryParams); SharedAccessSignature.RemoveSasQueryParameters(queryParams); if (useSas) { // Be careful to preserve the URL encoding in the signature queryParams.Append(CalculateSASStringForContainer(method, container), false); } return(new UriBuilder { Scheme = scheme, Host = account.BlobEndpoint.Host, Path = PathUtils.CombineContainerAndBlob(containerName, PathUtils.PathEncode(blobName)), Query = queryParams.ToString(), }); }
public static BlobRequestOptions CreateRequestOptions(this RequestQueryParameters queryParams) { return(new BlobRequestOptions { ServerTimeout = queryParams.Timeout, }); }
public void SharedKeyLiteSignatureTest() { // Taken directly from the payload emitted by the .NET Storage FX var headers = new List <Tuple <string, string> >() { Tuple.Create("User-Agent", "WA-Storage/4.3.0 (.NET CLR 4.0.30319.34014; Win32NT 6.2.9200.0)"), Tuple.Create("x-ms-version", "2014-02-14"), Tuple.Create("x-ms-client-request-id", "5bdcb4d9-bd21-44a6-a086-24d9fa9ec2b7"), Tuple.Create("x-ms-date", "Thu, 30 Oct 2014 21:32:29 GMT"), Tuple.Create("Connection", "Keep-Alive"), Tuple.Create("Expect", "100-continue"), Tuple.Create("Host", "dashstorage1.blob.core.windows.net"), }; var queryParams = new List <Tuple <string, string> >() { Tuple.Create("restype", "container"), Tuple.Create("comp", "list"), Tuple.Create("prefix", "te"), Tuple.Create("include", "snapshots"), Tuple.Create("INCLUDE", "uncommittedblobs,metadata,copy") }; Assert.AreEqual("+C5fkZr8g80qF5vzPeLCnuaaA2pG8jTZRdmhKkjZt2g=", SharedKey.GenerateSignature(true, true, "GET", "/test", RequestHeaders.Create(headers.ToLookup(header => header.Item1, header => header.Item2)), RequestQueryParameters.Create(queryParams.ToLookup(queryParam => queryParam.Item1, queryParam => queryParam.Item2)), "", ""), "Generated SharedKeyLite signature should match expected one 1"); // Taken directly from the payload emitted by the .NET Storage FX headers = new List <Tuple <string, string> >() { Tuple.Create("User-Agent", "WA-Storage/4.3.0 (.NET CLR 4.0.30319.34014; Win32NT 6.2.9200.0)"), Tuple.Create("x-ms-version", "2014-02-14"), Tuple.Create("Content-Type", "application/octet-stream"), Tuple.Create("Content-MD5", "LHmMkMS8mTXh0bRP4e4Ptw=="), Tuple.Create("Content-Language", "EN-US"), Tuple.Create("Content-Encoding", "gzip"), Tuple.Create("x-ms-blob-type", "BlockBlob"), Tuple.Create("If-Match", "DummyETag"), Tuple.Create("x-ms-client-request-id", "f71ce734-540f-44a6-a68e-7acaa6730daa"), Tuple.Create("x-ms-date", "Thu, 30 Oct 2014 21:53:09 GMT"), Tuple.Create("Content-Length", "423"), Tuple.Create("Connection", "Keep-Alive"), Tuple.Create("Expect", "100-continue"), Tuple.Create("Host", "dashstorage1.blob.core.windows.net"), }; Assert.AreEqual("2D9i7xldeRtls7/qW+lSgwYQEWx6aNbtTKPFhzfR7Dw=", SharedKey.GenerateSignature(false, true, "PUT", "/test/test.txt", RequestHeaders.Create(headers.ToLookup(header => header.Item1, header => header.Item2)), RequestQueryParameters.Empty, "", "423"), "Generated SharedKeyLite signature should match expected one 1"); }
public async Task <IActionResult> GetMyRequests([FromBody] RequestQueryParameters parameters) { parameters.UserEmail = CurrentUserEmail; var requestsfromrepo = await _wqService.LoadMyRequests(parameters); var data = Mapper.Map <IEnumerable <AllRequestPassedItem> >(requestsfromrepo); CreatePagingMetadata(requestsfromrepo, "GetMyRequests", parameters); return(Ok(data)); }
private static bool VerifyRequestAuthorization(string signature, bool usePrimaryKey, bool liteAlgorithm, string method, string uriPath, RequestHeaders headers, RequestQueryParameters queryParams, string requestDate, string contentLength) { if (!SharedKeySignature.HasKey(usePrimaryKey)) { return(false); } else if (signature == GenerateSignature(usePrimaryKey, liteAlgorithm, method, uriPath, headers, queryParams, requestDate, contentLength)) { return(true); } return(false); }
public async Task <PagedList <AllRequests> > GetRequests(RequestQueryParameters parameters) { var orderedList = _requestsRepository.GetDbSet().OrderBy(parameters.OrderBy).AsQueryable(); if (!string.IsNullOrEmpty(parameters.SearchQuery)) { orderedList = orderedList.Where(x => x.PROCESS_NAME.Contains(parameters.SearchQuery) || x.REF_ID.Contains(parameters.SearchQuery) || x.JOB_STATUS.Contains(parameters.SearchQuery) || x.JOB_STATUS.Contains(parameters.SearchQuery) || x.CurrentStage.Contains(parameters.SearchQuery)); } if (!string.IsNullOrEmpty(parameters.ProcessName)) { orderedList = orderedList.Where(x => x.PROCESS_NAME.Contains(parameters.ProcessName)); } if (!string.IsNullOrEmpty(parameters.REF_ID)) { orderedList = orderedList.Where(x => x.REF_ID.Contains(parameters.REF_ID)); } if (!string.IsNullOrEmpty(parameters.JOB_STATUS)) { orderedList = orderedList.Where(x => x.JOB_STATUS.Contains(parameters.JOB_STATUS)); } if (!string.IsNullOrEmpty(parameters.CurrentStage)) { orderedList = orderedList.Where(x => x.CurrentStage.Contains(parameters.CurrentStage)); } if (!string.IsNullOrEmpty(parameters.UserEmail)) { orderedList = orderedList.Where(x => x.EMP_EMAIL == parameters.UserEmail); } if (parameters.FromDate.HasValue) { orderedList = orderedList.Where(x => x.Request_Date <= parameters.FromDate); } if (parameters.ToDate.HasValue) { orderedList = orderedList.Where(x => x.Request_Date <= parameters.FromDate); } var pagedList = await PagedList <AllRequests> .Create(orderedList, parameters.PageNumber, parameters.PageSize); return(pagedList); }
public static void RemoveSasQueryParameters(RequestQueryParameters queryParams) { // The general pattern is that a request (majority of requests will be non-SAS). Therefore, process the query params // in the request url until we find a SAS param. At that point switch to removing from the URL. foreach (var queryParam in queryParams) { if (SasParameters.Contains(queryParam.Key)) { foreach (var sasParam in SasParameters) { queryParams.Remove(sasParam); } break; } } }
static string GetCanonicalizedResource(bool liteAlgorithm, string uriPath, RequestQueryParameters queryParams, string accountName) { string commonPrefix = "/" + accountName + uriPath; if (liteAlgorithm) { var compParam = queryParams.Value <string>("comp"); return(commonPrefix + (!String.IsNullOrWhiteSpace(compParam) ? "?comp=" + compParam : "")); } else { if (queryParams.Any()) { return(commonPrefix + "\n" + String.Join("\n", queryParams .OrderBy(queryParam => queryParam.Key, StringComparer.OrdinalIgnoreCase) .Select(queryParam => SharedKeySignature.FormatCanonicalizedValues(queryParam)))); } return(commonPrefix); } }
public static string GenerateSignature(bool usePrimaryKey, bool liteAlgorithm, string method, string uriPath, RequestHeaders headers, RequestQueryParameters queryParams, string requestDate, string contentLength) { // Signature scheme is described at: http://msdn.microsoft.com/en-us/library/azure/dd179428.aspx // and the SDK implementation is at: https://github.com/Azure/azure-storage-net/tree/master/Lib/ClassLibraryCommon/Auth/Protocol Func <string> stringToSignFactory = null; if (liteAlgorithm) { stringToSignFactory = () => String.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}", method, headers.Value("Content-MD5", String.Empty), headers.Value("Content-Type", String.Empty), requestDate, SharedKeySignature.GetCanonicalizedHeaders(headers), GetCanonicalizedResource(liteAlgorithm, uriPath, queryParams, SharedKeySignature.AccountName)); } else { stringToSignFactory = () => String.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n{6}\n{7}\n{8}\n{9}\n{10}\n{11}\n{12}\n{13}", method, headers.Value("Content-Encoding", String.Empty), headers.Value("Content-Language", String.Empty), contentLength, headers.Value("Content-MD5", String.Empty), headers.Value("Content-Type", String.Empty), requestDate, headers.Value("If-Modified-Since", String.Empty), headers.Value("If-Match", String.Empty), headers.Value("If-None-Match", String.Empty), headers.Value("If-Unmodified-Since", String.Empty), headers.Value("Range", String.Empty), SharedKeySignature.GetCanonicalizedHeaders(headers), GetCanonicalizedResource(liteAlgorithm, uriPath, queryParams, SharedKeySignature.AccountName)); } return(SharedKeySignature.GenerateSignature(stringToSignFactory, usePrimaryKey)); }
public async Task <PagedList <AllRequests> > LoadMyRequests(RequestQueryParameters parameters) { PagedList <AllRequests> MyRequests = await _agilityService.GetRequests(parameters); return(MyRequests); }
public static async Task <bool> IsAuthorizedAsync(IHttpRequestWrapper request, RequestHeaders headers, RequestQueryParameters queryParams, bool ignoreRequestAge) { var requestUriParts = request.UriParts; var resourceType = queryParams.Value <string>(ParamResourceType, String.Empty).ToLowerInvariant(); DateTimeOffset?start = queryParams.Value(ParamStartTime, DateTimeOffset.UtcNow); DateTimeOffset?expiry = queryParams.Value(ParamExpiryTime, DateTimeOffset.MinValue); if (expiry == DateTimeOffset.MinValue) { expiry = null; } SharedAccessBlobPermissions permissions = SharedAccessBlobPolicy.PermissionsFromString(queryParams.Value(ParamPermissions, String.Empty)); // Determine validity of the structure first if (requestUriParts.IsAccountRequest) { // SAS keys are not valid for account operations return(false); } else if (requestUriParts.IsContainerRequest && resourceType != "c") { return(false); } else if (requestUriParts.IsBlobRequest && resourceType.IndexOfAny(new [] { 'c', 'b' }) == -1) { return(false); } var storedPolicyId = queryParams.Value <string>(ParamStoredPolicy); if (!String.IsNullOrWhiteSpace(storedPolicyId)) { // Validate that we're not duplicating values for both stored access policy & url var storedPolicy = await GetStoredPolicyForContainer(requestUriParts.Container, storedPolicyId); if (storedPolicy == null) { return(false); } if (storedPolicy.SharedAccessStartTime.HasValue) { start = storedPolicy.SharedAccessStartTime; } if (storedPolicy.SharedAccessExpiryTime.HasValue) { if (expiry.HasValue) { return(false); } expiry = storedPolicy.SharedAccessExpiryTime; } if (queryParams.Contains(ParamPermissions)) { return(false); } permissions = storedPolicy.Permissions; } if (!expiry.HasValue || permissions == SharedAccessBlobPermissions.None) { return(false); } else if (!ignoreRequestAge && (start.Value > DateTimeOffset.UtcNow || expiry.Value < DateTimeOffset.UtcNow)) { return(false); } // Verify the assigned permissions line up with the requested operation StorageOperationTypes requestOperation = StorageOperations.GetBlobOperation(request); switch (requestOperation) { case StorageOperationTypes.GetBlob: case StorageOperationTypes.GetBlobMetadata: case StorageOperationTypes.GetBlobProperties: case StorageOperationTypes.GetBlockList: case StorageOperationTypes.GetPageRanges: if (!permissions.IsFlagSet(SharedAccessBlobPermissions.Read)) { return(false); } break; case StorageOperationTypes.AbortCopyBlob: case StorageOperationTypes.CopyBlob: case StorageOperationTypes.LeaseBlob: case StorageOperationTypes.PutBlob: case StorageOperationTypes.PutBlock: case StorageOperationTypes.PutBlockList: case StorageOperationTypes.PutPage: case StorageOperationTypes.SetBlobMetadata: case StorageOperationTypes.SetBlobProperties: case StorageOperationTypes.SnapshotBlob: if (!permissions.IsFlagSet(SharedAccessBlobPermissions.Write)) { return(false); } break; case StorageOperationTypes.DeleteBlob: if (!permissions.IsFlagSet(SharedAccessBlobPermissions.Delete)) { return(false); } break; case StorageOperationTypes.ListBlobs: if (!permissions.IsFlagSet(SharedAccessBlobPermissions.List)) { return(false); } break; default: // All other operations are not supported by SAS uris return(false); } DateTimeOffset sasVersion = queryParams.Value(ParamVersion, StorageServiceVersions.Version_2009_09_19); Func <string> stringToSignFactory = null; Func <string> baseStringToSign = () => String.Format("{0}\n{1}\n{2}\n{3}\n{4}", queryParams.Value <string>(ParamPermissions), queryParams.Value <string>(ParamStartTime), queryParams.Value <string>(ParamExpiryTime), GetCanonicalizedResource(requestUriParts, resourceType), queryParams.Value <string>(ParamStoredPolicy)); Func <string> v2012_02_12StringToSign = () => String.Format("{0}\n{1}", baseStringToSign(), queryParams.Value <string>(ParamVersion)); if (sasVersion < StorageServiceVersions.Version_2012_02_12) { stringToSignFactory = baseStringToSign; } else if (sasVersion == StorageServiceVersions.Version_2012_02_12) { stringToSignFactory = v2012_02_12StringToSign; } else { stringToSignFactory = () => String.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}", v2012_02_12StringToSign(), queryParams.Value <string>(ParamCacheControl), queryParams.Value <string>(ParamContentDisposition), queryParams.Value <string>(ParamContentEncoding), queryParams.Value <string>(ParamContentLang), queryParams.Value <string>(ParamContentType)); } string signature = queryParams.Value <string>(ParamSignature); var usingPrimaryKey = new[] { true, false }; int matchIndex = Array.FindIndex(usingPrimaryKey, usePrimaryKey => VerifySignature(signature, usePrimaryKey, stringToSignFactory)); if (matchIndex != -1) { // We can't sign the redirection response when the request uses a SAS key - preserve the matching key, however request.AuthenticationScheme = String.Empty; request.AuthenticationKey = usingPrimaryKey[matchIndex] ? SharedKeySignature.PrimaryAccountKey : SharedKeySignature.SecondaryAccountKey; return(true); } return(false); }
public static bool IsRequestType(RequestQueryParameters queryParams) { return(queryParams.Contains(ParamResourceType) && queryParams.Contains(ParamSignature)); }
public void SharedKeySignatureTest() { // Taken directly from the payload emitted by the .NET Storage FX var headers = new List <Tuple <string, string> >() { Tuple.Create("User-Agent", "WA-Storage/4.3.0 (.NET CLR 4.0.30319.34014; Win32NT 6.2.9200.0)"), Tuple.Create("Content-Length", "423"), Tuple.Create("Content-MD5", "LHmMkMS8mTXh0bRP4e4Ptw=="), Tuple.Create("Content-MD5", "LHmMkMS8mTXh0bRP4e4Ptw=="), Tuple.Create("x-ms-blob-type", "BlockBlob"), Tuple.Create("x-ms-client-request-id", "82370d95-e820-4817-bd3f-6c266544ee8b"), Tuple.Create("x-ms-date", "Thu, 30 Oct 2014 17:31:22 GMT"), Tuple.Create("x-ms-version", "2014-02-14"), Tuple.Create("Connection", "Keep-Alive"), Tuple.Create("Expect", "100-continue"), Tuple.Create("Host", "dashstorage1.blob.core.windows.net"), }; Assert.AreEqual("mDTyDIDy8yt7D81qAmYEYiXH1X/bmBHJF2+ZPn/r74k=", SharedKey.GenerateSignature(true, false, "PUT", "/test/test.txt", RequestHeaders.Create(headers.ToLookup(header => header.Item1, header => header.Item2)), RequestQueryParameters.Empty, "", "423"), "Generated SharedKey signature should match expected one 1"); // Taken directly from the payload emitted by the .NET Storage FX headers = new List <Tuple <string, string> >() { Tuple.Create("User-Agent", "WA-Storage/4.3.0 (.NET CLR 4.0.30319.34014; Win32NT 6.2.9200.0)"), Tuple.Create("Content-Length", "423"), Tuple.Create("Content-MD5", "LHmMkMS8mTXh0bRP4e4Ptw=="), Tuple.Create("x-ms-blob-type", "BlockBlob"), Tuple.Create("x-ms-client-request-id", "TestRequest1"), Tuple.Create("x-ms-date", "Thu, 30 Oct 2014 19:48:43 GMT"), Tuple.Create("x-ms-version", "2014-02-14"), Tuple.Create("x-ms-test", "testvalue"), Tuple.Create("x-test", "differentvalue"), Tuple.Create("Connection", "Keep-Alive"), Tuple.Create("Expect", "100-continue"), Tuple.Create("Host", "dashstorage1.blob.core.windows.net"), }; Assert.AreEqual("9q8Xz2jAkDaNpLeDoOUAo5hfZ3nbg696xt5F17wcX7Y=", SharedKey.GenerateSignature(false, false, "PUT", "/test/test.txt", RequestHeaders.Create(headers.ToLookup(header => header.Item1, header => header.Item2)), RequestQueryParameters.Empty, "", "423"), "Generated SharedKey signature should match expected one 2"); // Taken directly from the payload emitted by the .NET Storage FX headers = new List <Tuple <string, string> >() { Tuple.Create("User-Agent", "WA-Storage/4.3.0 (.NET CLR 4.0.30319.34014; Win32NT 6.2.9200.0)"), Tuple.Create("Content-Length", "423"), Tuple.Create("Content-MD5", "LHmMkMS8mTXh0bRP4e4Ptw=="), Tuple.Create("x-ms-version", "2014-02-14"), Tuple.Create("x-ms-blob-type", "BlockBlob"), Tuple.Create("x-ms-client-request-id", "d0863cd4-ae43-4dd4-aa27-eff01d30b5cf"), Tuple.Create("x-ms-date", "Thu, 30 Oct 2014 20:15:46 GMT"), Tuple.Create("If-Modified-Since", "Thu, 30 Oct 2014 20:15:41 GMT"), Tuple.Create("Connection", "Keep-Alive"), Tuple.Create("Expect", "100-continue"), Tuple.Create("Host", "dashstorage1.blob.core.windows.net"), }; Assert.AreEqual("21rAYhnoRQQu6MmxXj6W5Rx3YWI8OCjO50CNNniohAA=", SharedKey.GenerateSignature(true, false, "PUT", "/test/test.txt", RequestHeaders.Create(headers.ToLookup(header => header.Item1, header => header.Item2)), RequestQueryParameters.Empty, "", "423"), "Generated SharedKey signature should match expected one 3"); // Taken directly from the payload emitted by the .NET Storage FX headers = new List <Tuple <string, string> >() { Tuple.Create("User-Agent", "WA-Storage/4.3.0 (.NET CLR 4.0.30319.34014; Win32NT 6.2.9200.0)"), Tuple.Create("x-ms-version", "2014-02-14"), Tuple.Create("Content-Type", "application/octet-stream"), Tuple.Create("Content-MD5", "LHmMkMS8mTXh0bRP4e4Ptw=="), Tuple.Create("Content-Language", "EN-US"), Tuple.Create("Content-Encoding", "gzip"), Tuple.Create("x-ms-blob-type", "BlockBlob"), Tuple.Create("If-Match", "DummyETag"), Tuple.Create("x-ms-client-request-id", "93399f8e-6ce2-4020-81a4-4f1f53f427fd"), Tuple.Create("x-ms-date", "Thu, 30 Oct 2014 20:46:48 GMT"), Tuple.Create("Connection", "Keep-Alive"), Tuple.Create("Content-Length", "423"), Tuple.Create("Expect", "100-continue"), Tuple.Create("Host", "dashstorage1.blob.core.windows.net"), }; Assert.AreEqual("LzmxJ091fSbkczQfZErnqG0QEbsYQ+/mKx4gyBIjmFA=", SharedKey.GenerateSignature(false, false, "PUT", "/test/test.txt", RequestHeaders.Create(headers.ToLookup(header => header.Item1, header => header.Item2)), RequestQueryParameters.Empty, "", "423"), "Generated SharedKey signature should match expected one 4"); // Taken directly from the payload emitted by the .NET Storage FX headers = new List <Tuple <string, string> >() { Tuple.Create("User-Agent", "WA-Storage/4.3.0 (.NET CLR 4.0.30319.34014; Win32NT 6.2.9200.0)"), Tuple.Create("x-ms-version", "2014-02-14"), Tuple.Create("x-ms-client-request-id", "9e51b5a3-2dff-4fb2-98f8-c7cfe05a223a"), Tuple.Create("x-ms-date", "Thu, 30 Oct 2014 20:55:13 GMT"), Tuple.Create("Content-Length", "0"), Tuple.Create("Connection", "Keep-Alive"), Tuple.Create("Expect", "100-continue"), Tuple.Create("Host", "dashstorage1.blob.core.windows.net"), }; var queryParams = new List <Tuple <string, string> >() { Tuple.Create("restype", "container"), Tuple.Create("comp", "list"), Tuple.Create("prefix", "te"), Tuple.Create("include", "snapshots"), Tuple.Create("INCLUDE", "uncommittedblobs,metadata,copy"), }; Assert.AreEqual("C0mPsPAiMs+4qlDQXGXMXpRGUkQgyMLzOHBiCmoC4LE=", SharedKey.GenerateSignature(true, false, "GET", "/test", RequestHeaders.Create(headers.ToLookup(header => header.Item1, header => header.Item2)), RequestQueryParameters.Create(queryParams.ToLookup(queryParam => queryParam.Item1, queryParam => queryParam.Item2)), "", ""), "Generated SharedKey signature should match expected one 5"); headers = new List <Tuple <string, string> >() { Tuple.Create("User-Agent", "WA-Storage/4.3.0 (.NET CLR 4.0.30319.34014; Win32NT 6.2.9200.0)"), Tuple.Create("x-ms-version", "2014-02-14"), Tuple.Create("x-ms-client-request-id", "9e51b5a3-2dff-4fb2-98f8-c7cfe05a223a"), Tuple.Create("x-ms-date", "Thu, 30 Oct 2014 20:55:13 GMT"), Tuple.Create("Content-Length", "0"), Tuple.Create("Connection", "Keep-Alive"), Tuple.Create("Expect", "100-continue"), Tuple.Create("Host", "dashstorage1.blob.core.windows.net"), }; Assert.AreEqual("9ADGhBpIykIHJ+egWUVSP0LyzFF6aV9hPrT+6++IOPA=", SharedKey.GenerateSignature(true, false, "PUT", "/test/TEST%20Encoded", RequestHeaders.Create(headers.ToLookup(header => header.Item1, header => header.Item2)), RequestQueryParameters.Empty, "", "0"), "Generated SharedKey signature should match expected one 6"); }
public static bool IsAuthorized(IHttpRequestWrapper request, RequestHeaders headers, RequestQueryParameters queryParams, bool ignoreRequestAge) { // Quick request age check var authHeader = headers.Value <string>("Authorization"); string requestDateHeader = headers.Value <string>("x-ms-date"); string dateHeader = String.Empty; if (String.IsNullOrWhiteSpace(requestDateHeader)) { requestDateHeader = headers.Value <string>("Date"); dateHeader = requestDateHeader; } if (String.IsNullOrWhiteSpace(requestDateHeader)) { // One of the date headers is mandatory return(false); } if (!ignoreRequestAge) { DateTime requestDate; if (!DateTime.TryParse(requestDateHeader, out requestDate)) { return(false); } else if (requestDate < DateTime.Now.AddMinutes(-15)) { return(false); } } var parts = authHeader.Split(' ', ':'); if (parts.Length != 3) { return(false); } else if (parts[0] != SharedKeySignature.AlgorithmSharedKey && parts[0] != SharedKeySignature.AlgorithmSharedKeyLite) { return(false); } var account = parts[1]; var signature = parts[2]; if (!String.Equals(account, SharedKeySignature.AccountName, StringComparison.OrdinalIgnoreCase)) { return(false); } // We have to deal with multiple encodings (the spec is a bit ambiguous on what an 'encoded' path actually is). // Only run the validation if the encodings result in different strings var requestUriParts = request.UriParts; var pathsToCheck = new List <string>() { requestUriParts.OriginalUriPath }; var unencodedPath = requestUriParts.PublicUriPath; if (unencodedPath != pathsToCheck[0]) { pathsToCheck.Add(unencodedPath); } var alternateEncodingPaths = AlternateEncodeString(pathsToCheck[0]); if (alternateEncodingPaths != null) { pathsToCheck.AddRange(alternateEncodingPaths); } // For some verbs we can't tell if the Content-Length header was specified as 0 or that IIS/UrlRewrite/ASP.NET has constructed // the header value for us. The difference is significant to the signature as content length is included for SharedKey bool fullKeyAlgorithm = parts[0] == SharedKeySignature.AlgorithmSharedKey; bool runBlankContentLengthComparison = false; string method = request.HttpMethod.ToUpper(); var contentLength = headers.Value("Content-Length", String.Empty); if (fullKeyAlgorithm) { int length; if (!int.TryParse(contentLength, out length) || length <= 0) { // Preserve a Content-Length: 0 header for PUT methods runBlankContentLengthComparison = !method.Equals(WebRequestMethods.Http.Put, StringComparison.OrdinalIgnoreCase); } } var validationChecks = pathsToCheck.SelectMany(uriPath => new[] { runBlankContentLengthComparison?Tuple.Create(true, uriPath, String.Empty) : null, Tuple.Create(true, uriPath, contentLength), runBlankContentLengthComparison ? Tuple.Create(false, uriPath, String.Empty) : null, Tuple.Create(false, uriPath, contentLength), }) .Where(check => check != null) .ToArray(); var evaluationResult = validationChecks .FirstOrDefault(validatationCheck => VerifyRequestAuthorization(signature, validatationCheck.Item1, !fullKeyAlgorithm, method, validatationCheck.Item2, headers, queryParams, dateHeader, validatationCheck.Item3)); if (evaluationResult != null) { // Remember the Auth Scheme & Key for when we have to sign the response request.AuthenticationScheme = parts[0]; request.AuthenticationKey = evaluationResult.Item1 ? SharedKeySignature.PrimaryAccountKey : SharedKeySignature.SecondaryAccountKey; return(true); } DashTrace.TraceWarning("Failed to authenticate SharedKey request: {0}:{1}:{2}:{3}:{4}", parts[0], account, method, request.Url, signature); return(false); }
public static StorageOperationTypes GetBlobOperation(string requestMethod, RequestUriParts requestUriParts, RequestQueryParameters queryParams, RequestHeaders headers) { var requestAttributes = new RequestAttributes { Method = new HttpMethod(requestMethod), UriParts = requestUriParts, QueryParams = queryParams, Headers = headers, }; if (requestUriParts.IsAccountRequest) { return(LookupBlobOperation(requestAttributes, _accountOperations)); } else if (requestUriParts.IsContainerRequest) { return(LookupBlobOperation(requestAttributes, _containerOperations)); } else if (requestUriParts.IsBlobRequest) { return(LookupBlobOperation(requestAttributes, _blobOperations)); } else { System.Diagnostics.Debug.Assert(false); } return(StorageOperationTypes.Unknown); }