Пример #1
0
        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(),
            });
        }
Пример #2
0
 public static BlobRequestOptions CreateRequestOptions(this RequestQueryParameters queryParams)
 {
     return(new BlobRequestOptions
     {
         ServerTimeout = queryParams.Timeout,
     });
 }
Пример #3
0
        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");
        }
Пример #4
0
        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));
        }
Пример #5
0
 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);
 }
Пример #6
0
        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);
        }
Пример #7
0
 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;
         }
     }
 }
Пример #8
0
        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);
            }
        }
Пример #9
0
        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));
        }
Пример #10
0
        public async Task <PagedList <AllRequests> > LoadMyRequests(RequestQueryParameters parameters)
        {
            PagedList <AllRequests> MyRequests = await _agilityService.GetRequests(parameters);

            return(MyRequests);
        }
Пример #11
0
        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);
        }
Пример #12
0
 public static bool IsRequestType(RequestQueryParameters queryParams)
 {
     return(queryParams.Contains(ParamResourceType) && queryParams.Contains(ParamSignature));
 }
Пример #13
0
        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");
        }
Пример #14
0
        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);
        }
Пример #15
0
        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);
        }