github.com/chnsz/golangsdk@v0.0.0-20240506093406-85a3fbfa605b/openstack/obs/authV4.go (about) 1 // Copyright 2019 Huawei Technologies Co.,Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use 3 // this file except in compliance with the License. You may obtain a copy of the 4 // License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software distributed 9 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 10 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 // specific language governing permissions and limitations under the License. 12 13 package obs 14 15 import ( 16 "strings" 17 "time" 18 ) 19 20 func getV4StringToSign(method, canonicalizedURL, queryURL, scope, longDate, payload string, signedHeaders []string, headers map[string][]string) string { 21 canonicalRequest := make([]string, 0, 10+len(signedHeaders)*4) 22 canonicalRequest = append(canonicalRequest, method) 23 canonicalRequest = append(canonicalRequest, "\n") 24 canonicalRequest = append(canonicalRequest, canonicalizedURL) 25 canonicalRequest = append(canonicalRequest, "\n") 26 canonicalRequest = append(canonicalRequest, queryURL) 27 canonicalRequest = append(canonicalRequest, "\n") 28 29 for _, signedHeader := range signedHeaders { 30 values, _ := headers[signedHeader] 31 for _, value := range values { 32 canonicalRequest = append(canonicalRequest, signedHeader) 33 canonicalRequest = append(canonicalRequest, ":") 34 canonicalRequest = append(canonicalRequest, value) 35 canonicalRequest = append(canonicalRequest, "\n") 36 } 37 } 38 canonicalRequest = append(canonicalRequest, "\n") 39 canonicalRequest = append(canonicalRequest, strings.Join(signedHeaders, ";")) 40 canonicalRequest = append(canonicalRequest, "\n") 41 canonicalRequest = append(canonicalRequest, payload) 42 43 _canonicalRequest := strings.Join(canonicalRequest, "") 44 45 var isSecurityToken bool 46 var securityToken []string 47 if securityToken, isSecurityToken = headers[HEADER_STS_TOKEN_OBS]; !isSecurityToken { 48 securityToken, isSecurityToken = headers[HEADER_STS_TOKEN_AMZ] 49 } 50 var query []string 51 if !isSecurityToken { 52 query = strings.Split(queryURL, "&") 53 for _, value := range query { 54 if strings.HasPrefix(value, HEADER_STS_TOKEN_AMZ+"=") || strings.HasPrefix(value, HEADER_STS_TOKEN_OBS+"=") { 55 if value[len(HEADER_STS_TOKEN_AMZ)+1:] != "" { 56 securityToken = []string{value[len(HEADER_STS_TOKEN_AMZ)+1:]} 57 isSecurityToken = true 58 } 59 } 60 } 61 } 62 logCanonicalRequest := _canonicalRequest 63 if isSecurityToken && len(securityToken) > 0 { 64 logCanonicalRequest = strings.Replace(logCanonicalRequest, securityToken[0], "******", -1) 65 } 66 doLog(LEVEL_DEBUG, "The v4 auth canonicalRequest:\n%s", logCanonicalRequest) 67 68 stringToSign := make([]string, 0, 7) 69 stringToSign = append(stringToSign, V4_HASH_PREFIX) 70 stringToSign = append(stringToSign, "\n") 71 stringToSign = append(stringToSign, longDate) 72 stringToSign = append(stringToSign, "\n") 73 stringToSign = append(stringToSign, scope) 74 stringToSign = append(stringToSign, "\n") 75 stringToSign = append(stringToSign, HexSha256([]byte(_canonicalRequest))) 76 77 _stringToSign := strings.Join(stringToSign, "") 78 79 return _stringToSign 80 } 81 82 // V4Auth is a wrapper for v4Auth 83 func V4Auth(ak, sk, region, method, canonicalizedURL, queryURL string, headers map[string][]string) map[string]string { 84 return v4Auth(ak, sk, region, method, canonicalizedURL, queryURL, headers) 85 } 86 87 func v4Auth(ak, sk, region, method, canonicalizedURL, queryURL string, headers map[string][]string) map[string]string { 88 var t time.Time 89 if val, ok := headers[HEADER_DATE_AMZ]; ok { 90 var err error 91 t, err = time.Parse(LONG_DATE_FORMAT, val[0]) 92 if err != nil { 93 t = time.Now().UTC() 94 } 95 } else if val, ok := headers[PARAM_DATE_AMZ_CAMEL]; ok { 96 var err error 97 t, err = time.Parse(LONG_DATE_FORMAT, val[0]) 98 if err != nil { 99 t = time.Now().UTC() 100 } 101 } else if val, ok := headers[HEADER_DATE_CAMEL]; ok { 102 var err error 103 t, err = time.Parse(RFC1123_FORMAT, val[0]) 104 if err != nil { 105 t = time.Now().UTC() 106 } 107 } else if val, ok := headers[strings.ToLower(HEADER_DATE_CAMEL)]; ok { 108 var err error 109 t, err = time.Parse(RFC1123_FORMAT, val[0]) 110 if err != nil { 111 t = time.Now().UTC() 112 } 113 } else { 114 t = time.Now().UTC() 115 } 116 shortDate := t.Format(SHORT_DATE_FORMAT) 117 longDate := t.Format(LONG_DATE_FORMAT) 118 119 signedHeaders, _headers := getSignedHeaders(headers) 120 121 credential, scope := getCredential(ak, region, shortDate) 122 123 payload := UNSIGNED_PAYLOAD 124 if val, ok := headers[HEADER_CONTENT_SHA256_AMZ]; ok { 125 payload = val[0] 126 } 127 stringToSign := getV4StringToSign(method, canonicalizedURL, queryURL, scope, longDate, payload, signedHeaders, _headers) 128 129 signature := getSignature(stringToSign, sk, region, shortDate) 130 131 ret := make(map[string]string, 3) 132 ret["Credential"] = credential 133 ret["SignedHeaders"] = strings.Join(signedHeaders, ";") 134 ret["Signature"] = signature 135 return ret 136 }