github.com/opentelekomcloud/gophertelekomcloud@v0.9.3/openstack/obs/authV4.go (about) 1 package obs 2 3 import ( 4 "strings" 5 "time" 6 ) 7 8 func getV4StringToSign(method, canonicalizedURL, queryURL, scope, longDate, payload string, signedHeaders []string, headers map[string][]string) string { 9 canonicalRequest := make([]string, 0, 10+len(signedHeaders)*4) 10 canonicalRequest = append(canonicalRequest, method) 11 canonicalRequest = append(canonicalRequest, "\n") 12 canonicalRequest = append(canonicalRequest, canonicalizedURL) 13 canonicalRequest = append(canonicalRequest, "\n") 14 canonicalRequest = append(canonicalRequest, queryURL) 15 canonicalRequest = append(canonicalRequest, "\n") 16 17 for _, signedHeader := range signedHeaders { 18 values := headers[signedHeader] 19 for _, value := range values { 20 canonicalRequest = append(canonicalRequest, signedHeader) 21 canonicalRequest = append(canonicalRequest, ":") 22 canonicalRequest = append(canonicalRequest, value) 23 canonicalRequest = append(canonicalRequest, "\n") 24 } 25 } 26 canonicalRequest = append(canonicalRequest, "\n") 27 canonicalRequest = append(canonicalRequest, strings.Join(signedHeaders, ";")) 28 canonicalRequest = append(canonicalRequest, "\n") 29 canonicalRequest = append(canonicalRequest, payload) 30 31 _canonicalRequest := strings.Join(canonicalRequest, "") 32 33 var isSecurityToken bool 34 var securityToken []string 35 if securityToken, isSecurityToken = headers[HEADER_STS_TOKEN_OBS]; !isSecurityToken { 36 securityToken, isSecurityToken = headers[HEADER_STS_TOKEN_AMZ] 37 } 38 var query []string 39 if !isSecurityToken { 40 query = strings.Split(queryURL, "&") 41 for _, value := range query { 42 if strings.HasPrefix(value, HEADER_STS_TOKEN_AMZ+"=") || strings.HasPrefix(value, HEADER_STS_TOKEN_OBS+"=") { 43 if value[len(HEADER_STS_TOKEN_AMZ)+1:] != "" { 44 securityToken = []string{value[len(HEADER_STS_TOKEN_AMZ)+1:]} 45 isSecurityToken = true 46 } 47 } 48 } 49 } 50 logCanonicalRequest := _canonicalRequest 51 if isSecurityToken && len(securityToken) > 0 { 52 logCanonicalRequest = strings.Replace(logCanonicalRequest, securityToken[0], "******", -1) 53 } 54 doLog(LEVEL_DEBUG, "The v4 auth canonicalRequest:\n%s", logCanonicalRequest) 55 56 stringToSign := make([]string, 0, 7) 57 stringToSign = append(stringToSign, V4_HASH_PREFIX) 58 stringToSign = append(stringToSign, "\n") 59 stringToSign = append(stringToSign, longDate) 60 stringToSign = append(stringToSign, "\n") 61 stringToSign = append(stringToSign, scope) 62 stringToSign = append(stringToSign, "\n") 63 stringToSign = append(stringToSign, HexSha256([]byte(_canonicalRequest))) 64 65 _stringToSign := strings.Join(stringToSign, "") 66 67 doLog(LEVEL_DEBUG, "The v4 auth stringToSign:\n%s", _stringToSign) 68 return _stringToSign 69 } 70 71 // V4Auth is a wrapper for v4Auth 72 func V4Auth(ak, sk, region, method, canonicalizedURL, queryURL string, headers map[string][]string) map[string]string { 73 return v4Auth(ak, sk, region, method, canonicalizedURL, queryURL, headers) 74 } 75 76 func v4Auth(ak, sk, region, method, canonicalizedURL, queryURL string, headers map[string][]string) map[string]string { 77 var t time.Time 78 if val, ok := headers[HEADER_DATE_AMZ]; ok { 79 var err error 80 t, err = time.Parse(LONG_DATE_FORMAT, val[0]) 81 if err != nil { 82 t = time.Now().UTC() 83 } 84 } else if val, ok := headers[PARAM_DATE_AMZ_CAMEL]; ok { 85 var err error 86 t, err = time.Parse(LONG_DATE_FORMAT, val[0]) 87 if err != nil { 88 t = time.Now().UTC() 89 } 90 } else if val, ok := headers[HEADER_DATE_CAMEL]; ok { 91 var err error 92 t, err = time.Parse(RFC1123_FORMAT, val[0]) 93 if err != nil { 94 t = time.Now().UTC() 95 } 96 } else if val, ok := headers[strings.ToLower(HEADER_DATE_CAMEL)]; ok { 97 var err error 98 t, err = time.Parse(RFC1123_FORMAT, val[0]) 99 if err != nil { 100 t = time.Now().UTC() 101 } 102 } else { 103 t = time.Now().UTC() 104 } 105 shortDate := t.Format(SHORT_DATE_FORMAT) 106 longDate := t.Format(LONG_DATE_FORMAT) 107 108 signedHeaders, _headers := getSignedHeaders(headers) 109 110 credential, scope := getCredential(ak, region, shortDate) 111 112 payload := UNSIGNED_PAYLOAD 113 if val, ok := headers[HEADER_CONTENT_SHA256_AMZ]; ok { 114 payload = val[0] 115 } 116 stringToSign := getV4StringToSign(method, canonicalizedURL, queryURL, scope, longDate, payload, signedHeaders, _headers) 117 118 signature := getSignature(stringToSign, sk, region, shortDate) 119 120 ret := make(map[string]string, 3) 121 ret["Credential"] = credential 122 ret["SignedHeaders"] = strings.Join(signedHeaders, ";") 123 ret["Signature"] = signature 124 return ret 125 }