You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.5 KiB

6 years ago
5 years ago
5 years ago
5 years ago
  1. package s3api
  2. import (
  3. "net/http"
  4. "strings"
  5. )
  6. // AWS Signature Version '4' constants.
  7. const (
  8. signV4Algorithm = "AWS4-HMAC-SHA256"
  9. signV2Algorithm = "AWS"
  10. iso8601Format = "20060102T150405Z"
  11. yyyymmdd = "20060102"
  12. )
  13. // Verify if request has JWT.
  14. func isRequestJWT(r *http.Request) bool {
  15. return strings.HasPrefix(r.Header.Get("Authorization"), "Bearer")
  16. }
  17. // Verify if request has AWS Signature Version '4'.
  18. func isRequestSignatureV4(r *http.Request) bool {
  19. return strings.HasPrefix(r.Header.Get("Authorization"), signV4Algorithm)
  20. }
  21. // Verify if request has AWS Signature Version '2'.
  22. func isRequestSignatureV2(r *http.Request) bool {
  23. return !strings.HasPrefix(r.Header.Get("Authorization"), signV4Algorithm) &&
  24. strings.HasPrefix(r.Header.Get("Authorization"), signV2Algorithm)
  25. }
  26. // Verify if request has AWS PreSign Version '4'.
  27. func isRequestPresignedSignatureV4(r *http.Request) bool {
  28. _, ok := r.URL.Query()["X-Amz-Credential"]
  29. return ok
  30. }
  31. // Verify request has AWS PreSign Version '2'.
  32. func isRequestPresignedSignatureV2(r *http.Request) bool {
  33. _, ok := r.URL.Query()["AWSAccessKeyId"]
  34. return ok
  35. }
  36. // Verify if request has AWS Post policy Signature Version '4'.
  37. func isRequestPostPolicySignatureV4(r *http.Request) bool {
  38. return strings.Contains(r.Header.Get("Content-Type"), "multipart/form-data") &&
  39. r.Method == http.MethodPost
  40. }
  41. // Verify if the request has AWS Streaming Signature Version '4'. This is only valid for 'PUT' operation.
  42. func isRequestSignStreamingV4(r *http.Request) bool {
  43. return r.Header.Get("x-amz-content-sha256") == streamingContentSHA256 &&
  44. r.Method == http.MethodPut
  45. }
  46. // Authorization type.
  47. type authType int
  48. // List of all supported auth types.
  49. const (
  50. authTypeUnknown authType = iota
  51. authTypeAnonymous
  52. authTypePresigned
  53. authTypePresignedV2
  54. authTypePostPolicy
  55. authTypeStreamingSigned
  56. authTypeSigned
  57. authTypeSignedV2
  58. authTypeJWT
  59. )
  60. // Get request authentication type.
  61. func getRequestAuthType(r *http.Request) authType {
  62. if isRequestSignatureV2(r) {
  63. return authTypeSignedV2
  64. } else if isRequestPresignedSignatureV2(r) {
  65. return authTypePresignedV2
  66. } else if isRequestSignStreamingV4(r) {
  67. return authTypeStreamingSigned
  68. } else if isRequestSignatureV4(r) {
  69. return authTypeSigned
  70. } else if isRequestPresignedSignatureV4(r) {
  71. return authTypePresigned
  72. } else if isRequestJWT(r) {
  73. return authTypeJWT
  74. } else if isRequestPostPolicySignatureV4(r) {
  75. return authTypePostPolicy
  76. } else if _, ok := r.Header["Authorization"]; !ok {
  77. return authTypeAnonymous
  78. }
  79. return authTypeUnknown
  80. }