aliyun-net-sdk-core/Auth/RoaSignatureComposer.cs (161 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ using System; using System.Collections.Generic; using System.Text; using Aliyun.Acs.Core.Http; using Aliyun.Acs.Core.Utils; namespace Aliyun.Acs.Core.Auth { public class RoaSignatureComposer : ISignatureComposer { protected const string QUERY_SEPARATOR = "&"; protected const string HEADER_SEPARATOR = "\n"; private static ISignatureComposer composer; public Dictionary<string, string> RefreshSignParameters(Dictionary<string, string> parameters, Signer signer, string accessKeyId, FormatType? format) { var immutableMap = new Dictionary<string, string>(parameters); DictionaryUtil.Add(immutableMap, "Date", ParameterHelper.GetRFC2616Date(DateTime.UtcNow)); if (null == format) { format = FormatType.RAW; } DictionaryUtil.Add(immutableMap, "Accept", ParameterHelper.FormatTypeToString(format)); DictionaryUtil.Add(immutableMap, "x-acs-signature-method", signer.GetSignerName()); DictionaryUtil.Add(immutableMap, "x-acs-signature-version", signer.GetSignerVersion()); if (signer.GetSignerType() != null) { DictionaryUtil.Add(immutableMap, "x-acs-signature-type", signer.GetSignerType()); } return immutableMap; } public string ComposeStringToSign(MethodType? method, string uriPattern, Signer signer, Dictionary<string, string> queries, Dictionary<string, string> headers, Dictionary<string, string> paths) { var sb = new StringBuilder(); sb.Append(method).Append(HEADER_SEPARATOR); if (headers.ContainsKey("Accept")) { sb.Append(headers["Accept"]); } sb.Append(HEADER_SEPARATOR); if (headers.ContainsKey("Content-MD5")) { sb.Append(headers["Content-MD5"]); } sb.Append(HEADER_SEPARATOR); if (headers.ContainsKey("Content-Type")) { sb.Append(headers["Content-Type"]); } sb.Append(HEADER_SEPARATOR); if (headers.ContainsKey("Date")) { sb.Append(headers["Date"]); } sb.Append(HEADER_SEPARATOR); var uri = ReplaceOccupiedParameters(uriPattern, paths); sb.Append(BuildCanonicalHeaders(headers, "x-acs-")); sb.Append(BuildQuerystring(uri, queries)); return sb.ToString(); } private string[] SplitSubResource(string uri) { var queIndex = uri.IndexOf("?"); var uriParts = new string[2]; if (-1 != queIndex) { uriParts[0] = uri.Substring(0, queIndex); uriParts[1] = uri.Substring(queIndex + 1); } else { uriParts[0] = uri; } return uriParts; } private string BuildQuerystring(string uri, Dictionary<string, string> queries) { var uriParts = SplitSubResource(uri); var sortMap = new Dictionary<string, string>(queries); if (null != uriParts[1]) { sortMap.Add(uriParts[1], null); } var queryBuilder = new StringBuilder(uriParts[0]); var sortedDictionary = SortDictionary(sortMap); if (0 < sortedDictionary.Count) { queryBuilder.Append("?"); } foreach (var e in sortedDictionary) { queryBuilder.Append(e.Key); if (null != e.Value) { queryBuilder.Append("=").Append(e.Value); } queryBuilder.Append(QUERY_SEPARATOR); } var querystring = queryBuilder.ToString(); if (querystring.EndsWith(QUERY_SEPARATOR)) { querystring = querystring.Substring(0, querystring.Length - 1); } return querystring; } protected string BuildCanonicalHeaders(Dictionary<string, string> headers, string headerBegin) { var sortMap = new Dictionary<string, string>(); foreach (var e in headers) { var key = e.Key.ToLower(); var val = e.Value; if (key.StartsWith(headerBegin)) { sortMap.Add(key, val); } } var sortedDictionary = SortDictionary(sortMap); var headerBuilder = new StringBuilder(); foreach (var e in sortedDictionary) { headerBuilder.Append(e.Key); headerBuilder.Append(':').Append(e.Value); headerBuilder.Append(HEADER_SEPARATOR); } return headerBuilder.ToString(); } public static string ReplaceOccupiedParameters(string url, Dictionary<string, string> paths) { var result = url; foreach (var entry in paths) { var key = entry.Key; var value = entry.Value; var target = "[" + key + "]"; result = result.Replace(target, value); } return result; } public static ISignatureComposer GetComposer() { if (null == composer) { composer = new RoaSignatureComposer(); } return composer; } private static IDictionary<string, string> SortDictionary(Dictionary<string, string> dic) { IDictionary<string, string> sortedDictionary = new SortedDictionary<string, string>(dic, StringComparer.Ordinal); return sortedDictionary; } public static void ClearComposer() { composer = null; } } }