/// <summary> /// 签名的具体实现 /// </summary> /// <param name="builder">http请求信息</param> /// <param name="credentials">证书信息</param> /// <returns>请求后的http 信息</returns> private SdkHttpFullRequestBuilder DoSign(SdkHttpFullRequestBuilder builder, Credentials credentials) { Credentials sanitizedCredentials = SanitizeCredentials(credentials); if (credentials.GetType() == typeof(SessionCredentials)) { AddSessionCredentials(builder, (SessionCredentials)credentials); } //20180627T065220Z //_overrddenDate = new DateTime(2018,6,27,6, 52, 20); SignerRequestParams signerRequestParams = new SignerRequestParams(builder, _overrddenDate, RegionName, ServiceName, ParameterConstant.JDCLOUD2_SIGNING_ALGORITHM); // SignerRequestParams AddHostHeader(ref builder); builder.Header(ParameterConstant.X_JDCLOUD_DATE, signerRequestParams.FormattedSigningDateTime); string contentSha256 = string.Empty; if (builder.GetHeaders() != null && builder.GetHeaders().ContainsKey(ParameterConstant.X_JDCLOUD_CONTENT_SHA256) && builder.GetHeaders()[ParameterConstant.X_JDCLOUD_CONTENT_SHA256] != null && builder.GetHeaders()[ParameterConstant.X_JDCLOUD_CONTENT_SHA256].Count > 0) { contentSha256 = builder.GetHeaders()[ParameterConstant.X_JDCLOUD_CONTENT_SHA256][0]; } else { contentSha256 = CalculateContentHash(builder); } string canonicalRequest = CreateCanonicalRequest(builder, contentSha256); string stringToSign = CreateStringToSign(canonicalRequest, signerRequestParams); byte[] signingKey = deriveSigningKey(credentials, signerRequestParams); byte[] signature = ComputeSignature(stringToSign, signingKey); builder.Header(ParameterConstant.AUTHORIZATION, BuildAuthorizationHeader(builder, signature, credentials, signerRequestParams)); return(builder); }
/// <summary> /// 添加头信息 /// </summary> /// <param name="builder">http请求信息</param> private void AddHostHeader(ref SdkHttpFullRequestBuilder builder) { var endPoint = builder.GetEndpoint(); if (endPoint == null) { throw new ArgumentNullException(" can not get the uri from de SdkHttpFullRequestBuilder , please check the param set "); } StringBuilder hostHeaderBuilder = new StringBuilder(endPoint.Host); if (SdkHttpUtils.IsUsingNonDefaultPort(endPoint)) { hostHeaderBuilder.Append(":").Append(endPoint.Port); } builder.Header(ParameterConstant.HOST, hostHeaderBuilder.ToString()); string contentSha256 = CalculateContentHash(builder); }
/// <summary> /// 进行签名操作 /// </summary> /// <param name="signRequest">http请求信息</param> /// <returns>返回签名后的需要添加的HTTP header 信息</returns> public Dictionary <string, string> Sign(SignRequest signRequest) { Dictionary <string, string> header = new Dictionary <string, string>(); // v4signer JdCloudSigner signer = new JdCloudSigner(); signer.SetRegionName(signRequest.Region); signer.SetServiceName(signRequest.ServiceName); String nonceId = Guid.NewGuid().ToString().ToLower(); //the default http request mothed is `GET` SdkHttpMethod method = SdkHttpMethod.GET; #if NET35 if (!string.IsNullOrEmpty(signRequest.RequestMothed) && !string.IsNullOrEmpty(signRequest.RequestMothed.Trim())) { method = (SdkHttpMethod)Enum.Parse(typeof(SdkHttpMethod), signRequest.RequestMothed.ToUpper()); } #else if (!string.IsNullOrWhiteSpace(signRequest.RequestMothed)) { if (!Enum.TryParse <SdkHttpMethod>(signRequest.RequestMothed.ToUpper(), out method)) { throw new ArgumentException("the http request mothed cast fail , not support ."); } } #endif Uri endPoint = new Uri(signRequest.Host); // Builder #if NET35 string signRequestContent = string.IsNullOrEmpty(signRequest.RequestContent) || string.IsNullOrEmpty(signRequest.RequestContent.Trim()) ? null : signRequest.RequestContent; SdkHttpFullRequestBuilder reqBuilder = DefaultSdkHttpFullRequest.Builder() .HttpMethod(method) .Endpoint(endPoint) .ResourcePath(SdkHttpUtils.UrlEncode(signRequest.Path, true)) .Header(ParameterConstant.X_JDCLOUD_NONCE, nonceId) // .Header(ParameterConstant.CONTENT_TYPE, signRequest.ContentType) .Content(signRequestContent) .QueryParameter(signRequest.QueryParam); #else SdkHttpFullRequestBuilder reqBuilder = DefaultSdkHttpFullRequest.Builder() .HttpMethod(method) .Endpoint(endPoint) .ResourcePath(SdkHttpUtils.UrlEncode(signRequest.Path, true)) .Header(ParameterConstant.X_JDCLOUD_NONCE, nonceId) // .Header(ParameterConstant.CONTENT_TYPE, signRequest.ContentType) .Content(string.IsNullOrWhiteSpace(signRequest.RequestContent) ? null : signRequest.RequestContent) .QueryParameter(signRequest.QueryParam); #endif //对http header 进行处理, 如果 请求为get head delete 默认不放置content-type 签名内不包含content-type if (method != SdkHttpMethod.GET && method != SdkHttpMethod.DELETE && method != SdkHttpMethod.HEAD) { reqBuilder.Header(ParameterConstant.CONTENT_TYPE, signRequest.ContentType); header.Add(ParameterConstant.CONTENT_TYPE, signRequest.ContentType); } // sign SdkHttpFullRequest signed = signer.Sign(reqBuilder, new Credentials(signRequest.Credentials.AccessKeyId(), signRequest.Credentials.SecretAccessKey())); var signedHeader = signed.GetHeaders(); header.Add(ParameterConstant.X_JDCLOUD_NONCE, nonceId); header.Add(ParameterConstant.X_JDCLOUD_DATE, signedHeader[ParameterConstant.X_JDCLOUD_DATE][0]); header.Add(ParameterConstant.AUTHORIZATION, signedHeader[ParameterConstant.AUTHORIZATION][0]); foreach (var item in signedHeader) { if (!header.ContainsKey(item.Key)) { header.Add(item.Key, item.Value[0]); } } return(header); }
/// <summary> /// 添加session 认证信息 /// </summary> /// <param name="mutableRequest">http请求信息</param> /// <param name="credentials">session 认证信息</param> protected override void AddSessionCredentials(SdkHttpFullRequestBuilder mutableRequest, SessionCredentials credentials) { mutableRequest.Header(ParameterConstant.X_JDCLOUD_SECURITY_TOKEN, credentials.SessionToken()); }