github.com/GuanceCloud/cliutils@v1.1.21/network/http/aksk.go (about) 1 // Unless explicitly stated otherwise all files in this repository are licensed 2 // under the MIT License. 3 // This product includes software developed at Guance Cloud (https://www.guance.com/). 4 // Copyright 2021-present Guance, Inc. 5 6 package http 7 8 import ( 9 "crypto/hmac" 10 "crypto/sha256" 11 "encoding/base64" 12 "fmt" 13 "net/http" 14 "sort" 15 "strings" 16 ) 17 18 type SignOption struct { 19 AuthorizationType string 20 SignHeaders []string // in order 21 SK string 22 AK string 23 Sign string 24 SignStr string 25 } 26 27 func DefaultSignOption(authType string, headers []string) *SignOption { 28 sort.Strings(headers) 29 30 return &SignOption{ 31 AuthorizationType: authType, 32 SignHeaders: headers, 33 } 34 } 35 36 func (o *SignOption) SignReq(r *http.Request) (string, error) { 37 signElems := []string{ 38 r.Method, 39 } 40 41 sort.Strings(o.SignHeaders) 42 43 for _, v := range o.SignHeaders { 44 signElems = append(signElems, r.Header.Get(v)) 45 } 46 47 o.SignStr = strings.Join(signElems, "\n") 48 49 h := hmac.New(sha256.New, []byte(o.SK)) 50 if _, err := h.Write([]byte(o.SignStr)); err != nil { 51 return "", err 52 } 53 54 return base64.StdEncoding.EncodeToString(h.Sum(nil)), nil 55 } 56 57 func (o *SignOption) ParseAuth(r *http.Request) error { 58 authHeader := r.Header.Get(`Authorization`) 59 60 parts := strings.Split(authHeader, " ") 61 switch len(parts) { 62 case 2: //nolint:gomnd 63 if parts[0] != o.AuthorizationType { 64 return fmt.Errorf("unknown authorization type %s, expect %s", parts[0], o.AuthorizationType) 65 } 66 67 signParts := strings.Split(parts[1], `:`) 68 if len(signParts) != 2 { //nolint:gomnd 69 return fmt.Errorf("invalid Authorization header, expect format `type access_key:sign'") 70 } 71 72 o.AK = signParts[0] 73 o.Sign = signParts[1] 74 return nil 75 76 default: 77 return fmt.Errorf("invalid Authorization header, expect format `type access_key:sign'") 78 } 79 }