Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

127 рядки
3.5 KiB

  1. package auth
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
  7. "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
  8. "net/http"
  9. "net/url"
  10. "strconv"
  11. "strings"
  12. "time"
  13. )
  14. func signRpcRequest(request requests.AcsRequest, signer Signer) (err error) {
  15. err = completeRpcSignParams(request, signer)
  16. if err != nil {
  17. return
  18. }
  19. if _, isContainsSign := request.GetQueryParams()["sign"]; isContainsSign {
  20. delete(request.GetQueryParams(), "sign")
  21. }
  22. stringToSign := buildRpcStringToSign(request)
  23. request.SetStringToSign(stringToSign)
  24. signature := signer.Sign(stringToSign, "&")
  25. request.GetQueryParams()["sign"] = signature
  26. debug("GrSdk sign: %s", signature)
  27. debug("GrSdk sign string: %s", stringToSign)
  28. debug("GrSdk sign: \r\n")
  29. return
  30. }
  31. func completeRpcSignParams(request requests.AcsRequest, signer Signer) (err error) {
  32. var accessKeyFrom string
  33. if accessKeyFrom, err = signer.GetAccessKeyFrom(); err != nil {
  34. return
  35. }
  36. queryParams := request.GetQueryParams()
  37. queryParams["access_time"] = fmt.Sprintf("%d", time.Now().Unix())
  38. queryParams["access_key"], err = signer.GetAccessKeyId()
  39. queryParams["access_from"] = accessKeyFrom
  40. if err != nil {
  41. return
  42. }
  43. request.GetHeaders()["Content-type"] = requests.Form
  44. request.GetHeaders()["Gr-Sdk-From"] = accessKeyFrom
  45. formString := utils.GetUrlFormedMap(request.GetFormParams())
  46. request.SetContent(bytes.NewBufferString(formString).Bytes())
  47. return
  48. }
  49. func buildRpcStringToSign(request requests.AcsRequest) (stringToSign string) {
  50. signParams := make(map[string]string)
  51. for key, value := range request.GetQueryParams() {
  52. signParams[key] = value
  53. }
  54. if strings.ToUpper(request.GetMethod()) == requests.POST {
  55. for key, value := range request.GetFormParams() {
  56. signParams[key] = value
  57. }
  58. }
  59. stringToSign = utils.GetUrlFormedMap(signParams)
  60. stringToSign = strings.Replace(stringToSign, "+", "%20", -1)
  61. stringToSign = strings.Replace(stringToSign, "*", "%2A", -1)
  62. stringToSign = strings.Replace(stringToSign, "%7E", "~", -1)
  63. stringToSign = url.QueryEscape(stringToSign)
  64. stringToSign = request.GetMethod() + "&%2F&" + stringToSign
  65. return
  66. }
  67. func unsignRpcRequest(request *http.Request, signer Signer) (err error) {
  68. signParams := make(map[string]string)
  69. for key, value := range request.URL.Query() {
  70. signParams[key] = value[0]
  71. }
  72. if strings.ToUpper(request.Method) == requests.POST {
  73. for key, value := range request.Form {
  74. signParams[key] = value[0]
  75. }
  76. }
  77. if accessKey, err := signer.GetAccessKeyId(); err != nil {
  78. return err
  79. } else if accessKey == "" {
  80. return errors.New("access key is not allow empty")
  81. } else if accessKey != signParams["access_key"] {
  82. return errors.New("illegal access key")
  83. }
  84. signValue, ok := signParams["sign"]
  85. if !ok {
  86. return errors.New("sign value is not exists")
  87. } else {
  88. delete(signParams, "sign")
  89. }
  90. stringToSign := utils.GetUrlFormedMap(signParams)
  91. stringToSign = strings.Replace(stringToSign, "+", "%20", -1)
  92. stringToSign = strings.Replace(stringToSign, "*", "%2A", -1)
  93. stringToSign = strings.Replace(stringToSign, "%7E", "~", -1)
  94. stringToSign = url.QueryEscape(stringToSign)
  95. stringToSign = request.Method + "&%2F&" + stringToSign
  96. debug("GrSdk sign: %s", stringToSign)
  97. if timestamp, err := strconv.ParseInt(signParams["access_time"], 10, 64); err != nil {
  98. return err
  99. } else {
  100. if time.Unix(timestamp, 0).Before(time.Now().Add(-5 * time.Minute)) {
  101. err = errors.New("sign timeout 5 minute")
  102. }
  103. }
  104. if signer.Sign(stringToSign, "&") != signValue {
  105. return errors.New("sign string is not correct")
  106. }
  107. return
  108. }