<PackageReference Include="Azure.Storage.Blobs" Version="12.23.0" />

StorageSharedKeyPipelinePolicy

HttpPipelinePolicy to sign requests using an Azure Storage shared key.
using Azure.Core; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Net.Http.Headers; using System.Text; namespace Azure.Storage { internal sealed class StorageSharedKeyPipelinePolicy { internal class HeaderComparer : IComparer<HttpHeader> { private static readonly HeaderStringComparer s_headerComparer = new HeaderStringComparer(); public int Compare(HttpHeader x, HttpHeader y) { return s_headerComparer.Compare(x.get_Name(), y.get_Name()); } } internal class HeaderStringComparer : IComparer<string> { private static readonly int[] s_table_lv0 = new int[128] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1820, 0, 1823, 1825, 1827, 1829, 0, 0, 0, 1837, 2051, 0, 0, 1843, 0, 3331, 3354, 3356, 3358, 3360, 3362, 3364, 3366, 3368, 3370, 0, 0, 0, 0, 0, 0, 0, 3586, 3593, 3594, 3610, 3617, 3619, 3621, 3628, 3634, 3637, 3638, 3656, 3665, 3696, 3708, 3710, 3721, 3722, 3729, 3737, 3743, 3746, 3748, 3750, 3751, 3753, 0, 0, 0, 1859, 1860, 1864, 3586, 3593, 3594, 3610, 3617, 3619, 3621, 3628, 3634, 3637, 3638, 3656, 3665, 3696, 3708, 3710, 3721, 3722, 3729, 3737, 3743, 3746, 3748, 3750, 3751, 3753, 0, 1868, 0, 1872, 0 }; private static readonly int[] s_table_lv2 = new int[128] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; private static readonly int[] s_table_lv4 = new int[128] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32786, 0, 0, 0, 0, 0, 33298, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; private static readonly int[][] s_tables = new int[3][] { s_table_lv0, s_table_lv2, s_table_lv4 }; public int Compare(string x, string y) { int num = 0; int num2 = 0; int num3 = 0; while (num < s_tables.Length) { if (num == s_tables.Length - 1 && num2 != num3) return num3 - num2; int num4 = (num2 >= x.Length) ? 1 : s_tables[num][x[num2]]; int num5 = (num3 >= y.Length) ? 1 : s_tables[num][y[num3]]; if (num4 == 1 && num5 == 1) { num2 = 0; num3 = 0; num++; } else if (num4 == num5) { num2++; num3++; } else if (num4 == 0) { num2++; } else { if (num5 != 0) return num4 - num5; num3++; } } return 0; } } private const bool IncludeXMsDate = true; private readonly StorageSharedKeyCredential _credentials; private static readonly HeaderComparer s_headerComparer = new HeaderComparer(); public StorageSharedKeyPipelinePolicy(StorageSharedKeyCredential credentials) : this() { _credentials = credentials; } public override void OnSendingRequest(HttpMessage message) { this.OnSendingRequest(message); string text = DateTimeOffset.UtcNow.ToString("r", CultureInfo.InvariantCulture); RequestHeaders headers = message.get_Request().get_Headers(); headers.SetValue("x-ms-date", text); string message2 = BuildStringToSign(message); string str = StorageSharedKeyCredentialInternals.ComputeSasSignature(_credentials, message2); string text2 = new AuthenticationHeaderValue("SharedKey", _credentials.get_AccountName() + ":" + str).ToString(); headers = message.get_Request().get_Headers(); headers.SetValue("Authorization", text2); } private string BuildStringToSign(HttpMessage message) { RequestHeaders headers = message.get_Request().get_Headers(); string text = default(string); headers.TryGetValue("Content-Encoding", ref text); headers = message.get_Request().get_Headers(); string text2 = default(string); headers.TryGetValue("Content-Language", ref text2); headers = message.get_Request().get_Headers(); string text3 = default(string); headers.TryGetValue("Content-MD5", ref text3); headers = message.get_Request().get_Headers(); string text4 = default(string); headers.TryGetValue("Content-Type", ref text4); headers = message.get_Request().get_Headers(); string text5 = default(string); headers.TryGetValue("If-Modified-Since", ref text5); headers = message.get_Request().get_Headers(); string text6 = default(string); headers.TryGetValue("If-Match", ref text6); headers = message.get_Request().get_Headers(); string text7 = default(string); headers.TryGetValue("If-None-Match", ref text7); headers = message.get_Request().get_Headers(); string text8 = default(string); headers.TryGetValue("If-Unmodified-Since", ref text8); headers = message.get_Request().get_Headers(); string text9 = default(string); headers.TryGetValue("Range", ref text9); string text10 = string.Empty; long num = default(long); if ((int)message.get_Request().get_Content() != 0 && message.get_Request().get_Content().TryComputeLength(ref num)) text10 = num.ToString(CultureInfo.InvariantCulture); Uri uri = message.get_Request().get_Uri().ToUri(); StringBuilder stringBuilder = new StringBuilder(uri.AbsolutePath.Length + 64); StringBuilder stringBuilder2 = stringBuilder; RequestMethod method = message.get_Request().get_Method(); stringBuilder2.Append(((object)method).ToString().ToUpperInvariant()).Append('\n'); stringBuilder.Append(text ?? "").Append('\n'); stringBuilder.Append(text2 ?? "").Append('\n'); stringBuilder.Append((text10 == "0") ? "" : (text10 ?? "")).Append('\n'); stringBuilder.Append(text3 ?? ""); stringBuilder.Append('\n'); stringBuilder.Append(text4 ?? "").Append('\n'); stringBuilder.Append('\n'); stringBuilder.Append(text5 ?? "").Append('\n'); stringBuilder.Append(text6 ?? "").Append('\n'); stringBuilder.Append(text7 ?? "").Append('\n'); stringBuilder.Append(text8 ?? "").Append('\n'); stringBuilder.Append(text9 ?? "").Append('\n'); BuildCanonicalizedHeaders(stringBuilder, message); BuildCanonicalizedResource(stringBuilder, uri); return stringBuilder.ToString(); } private static void BuildCanonicalizedHeaders(StringBuilder stringBuilder, HttpMessage message) { List<HttpHeader> list = new List<HttpHeader>(); RequestHeaders headers = message.get_Request().get_Headers(); foreach (HttpHeader item in headers) { HttpHeader current = item; if (current.get_Name().StartsWith("x-ms-", StringComparison.OrdinalIgnoreCase)) list.Add(new HttpHeader(current.get_Name().ToLowerInvariant(), current.get_Value())); } list.Sort(s_headerComparer); foreach (HttpHeader item2 in list) { HttpHeader current2 = item2; stringBuilder.Append(current2.get_Name()).Append(':').Append(current2.get_Value()) .Append('\n'); } } private void BuildCanonicalizedResource(StringBuilder stringBuilder, Uri resource) { stringBuilder.Append('/'); stringBuilder.Append(_credentials.get_AccountName()); if (resource.AbsolutePath.Length > 0) stringBuilder.Append(resource.AbsolutePath); else stringBuilder.Append('/'); IDictionary<string, string> queryParameters = resource.GetQueryParameters(); if (queryParameters.Count > 0) { foreach (string item in queryParameters.Keys.OrderBy((string key) => key, StringComparer.Ordinal)) { stringBuilder.Append('\n').Append(item.ToLowerInvariant()).Append(':') .Append(queryParameters[item]); } } } } }