s3api_auth.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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. func isRequestUnsignedStreaming(r *http.Request) bool {
  47. return r.Header.Get("x-amz-content-sha256") == streamingUnsignedPayload &&
  48. r.Method == http.MethodPut
  49. }
  50. // Authorization type.
  51. type authType int
  52. // List of all supported auth types.
  53. const (
  54. authTypeUnknown authType = iota
  55. authTypeAnonymous
  56. authTypePresigned
  57. authTypePresignedV2
  58. authTypePostPolicy
  59. authTypeStreamingSigned
  60. authTypeStreamingUnsigned
  61. authTypeSigned
  62. authTypeSignedV2
  63. authTypeJWT
  64. )
  65. // Get request authentication type.
  66. func getRequestAuthType(r *http.Request) authType {
  67. if isRequestSignatureV2(r) {
  68. return authTypeSignedV2
  69. } else if isRequestPresignedSignatureV2(r) {
  70. return authTypePresignedV2
  71. } else if isRequestSignStreamingV4(r) {
  72. return authTypeStreamingSigned
  73. } else if isRequestUnsignedStreaming(r) {
  74. return authTypeStreamingUnsigned
  75. } else if isRequestSignatureV4(r) {
  76. return authTypeSigned
  77. } else if isRequestPresignedSignatureV4(r) {
  78. return authTypePresigned
  79. } else if isRequestJWT(r) {
  80. return authTypeJWT
  81. } else if isRequestPostPolicySignatureV4(r) {
  82. return authTypePostPolicy
  83. } else if _, ok := r.Header["Authorization"]; !ok {
  84. return authTypeAnonymous
  85. }
  86. return authTypeUnknown
  87. }