Audit log claims from token (#6847)

This commit is contained in:
Harshavardhana 2018-11-21 20:03:24 -08:00 committed by Nitish Tiwari
parent d4265f9a13
commit 9e3fce441e
12 changed files with 128 additions and 86 deletions

View File

@ -57,7 +57,7 @@ type accessControlPolicy struct {
func (api objectAPIHandlers) GetBucketACLHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) GetBucketACLHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "GetBucketACL") ctx := newContext(r, w, "GetBucketACL")
defer logger.AuditLog(w, r, "GetBucketACL") defer logger.AuditLog(w, r, "GetBucketACL", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -106,7 +106,7 @@ func (api objectAPIHandlers) GetBucketACLHandler(w http.ResponseWriter, r *http.
func (api objectAPIHandlers) GetObjectACLHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) GetObjectACLHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "GetObjectACL") ctx := newContext(r, w, "GetObjectACL")
defer logger.AuditLog(w, r, "GetObjectACL") defer logger.AuditLog(w, r, "GetObjectACL", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]

View File

@ -19,10 +19,10 @@ package cmd
import ( import (
"bytes" "bytes"
"context" "context"
"crypto/subtle"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
@ -155,32 +155,56 @@ func getSessionToken(r *http.Request) (token string) {
return r.URL.Query().Get("X-Amz-Security-Token") return r.URL.Query().Get("X-Amz-Security-Token")
} }
// Fetch claims in the security token returned by the client and validate the token. // Fetch claims in the security token returned by the client, doesn't return
func getClaimsFromToken(r *http.Request, cred auth.Credentials) (map[string]interface{}, APIErrorCode) { // errors - upon errors the returned claims map will be empty.
func mustGetClaimsFromToken(r *http.Request) map[string]interface{} {
claims, _ := getClaimsFromToken(r)
return claims
}
// Fetch claims in the security token returned by the client.
func getClaimsFromToken(r *http.Request) (map[string]interface{}, error) {
claims := make(map[string]interface{})
token := getSessionToken(r)
if token == "" {
return claims, nil
}
stsTokenCallback := func(jwtToken *jwtgo.Token) (interface{}, error) { stsTokenCallback := func(jwtToken *jwtgo.Token) (interface{}, error) {
if _, ok := jwtToken.Method.(*jwtgo.SigningMethodHMAC); !ok { // JWT token for x-amz-security-token is signed with admin
return nil, fmt.Errorf("Unexpected signing method: %v", jwtToken.Header["alg"]) // secret key, temporary credentials become invalid if
} // server admin credentials change. This is done to ensure
if err := jwtToken.Claims.Valid(); err != nil { // that clients cannot decode the token using the temp
return nil, errAuthentication // secret keys and generate an entirely new claim by essentially
} // hijacking the policies. We need to make sure that this is
if claims, ok := jwtToken.Claims.(jwtgo.MapClaims); ok { // based an admin credential such that token cannot be decoded
if _, ok = claims["accessKey"].(string); !ok { // on the client side and is treated like an opaque value.
return nil, errInvalidAccessKeyID return []byte(globalServerConfig.GetCredential().SecretKey), nil
} }
// JWT token for x-amz-security-token is signed with admin p := &jwtgo.Parser{
// secret key, temporary credentials become invalid if ValidMethods: []string{
// server admin credentials change. This is done to ensure jwtgo.SigningMethodHS256.Alg(),
// that clients cannot decode the token using the temp jwtgo.SigningMethodHS512.Alg(),
// secret keys and generate an entirely new claim by essentially },
// hijacking the policies. We need to make sure that this is }
// based an admin credential such that token cannot be decoded jtoken, err := p.ParseWithClaims(token, jwtgo.MapClaims(claims), stsTokenCallback)
// on the client side and is treated like an opaque value. if err != nil {
return []byte(globalServerConfig.GetCredential().SecretKey), nil return nil, err
} }
if !jtoken.Valid {
return nil, errAuthentication return nil, errAuthentication
} }
claims := make(map[string]interface{}) v, ok := claims["accessKey"]
if !ok {
return nil, errInvalidAccessKeyID
}
if _, ok = v.(string); !ok {
return nil, errInvalidAccessKeyID
}
return claims, nil
}
// Fetch claims in the security token returned by the client and validate the token.
func checkClaimsFromToken(r *http.Request, cred auth.Credentials) (map[string]interface{}, APIErrorCode) {
token := getSessionToken(r) token := getSessionToken(r)
if token == "" { if token == "" {
return nil, ErrNone return nil, ErrNone
@ -188,16 +212,12 @@ func getClaimsFromToken(r *http.Request, cred auth.Credentials) (map[string]inte
if token != "" && cred.AccessKey == "" { if token != "" && cred.AccessKey == "" {
return nil, ErrNoAccessKey return nil, ErrNoAccessKey
} }
if token != cred.SessionToken { if subtle.ConstantTimeCompare([]byte(token), []byte(cred.SessionToken)) != 1 {
return nil, ErrInvalidToken return nil, ErrInvalidToken
} }
p := &jwtgo.Parser{} claims, err := getClaimsFromToken(r)
jtoken, err := p.ParseWithClaims(token, jwtgo.MapClaims(claims), stsTokenCallback)
if err != nil { if err != nil {
return nil, toAPIErrorCode(context.Background(), errAuthentication) return nil, toAPIErrorCode(context.Background(), err)
}
if !jtoken.Valid {
return nil, toAPIErrorCode(context.Background(), errAuthentication)
} }
return claims, ErrNone return claims, ErrNone
} }
@ -256,7 +276,7 @@ func checkRequestAuthType(ctx context.Context, r *http.Request, action policy.Ac
r.Body = ioutil.NopCloser(bytes.NewReader(payload)) r.Body = ioutil.NopCloser(bytes.NewReader(payload))
} }
claims, s3Err := getClaimsFromToken(r, cred) claims, s3Err := checkClaimsFromToken(r, cred)
if s3Err != ErrNone { if s3Err != ErrNone {
return s3Err return s3Err
} }
@ -421,7 +441,7 @@ func isPutAllowed(atype authType, bucketName, objectName string, r *http.Request
return s3Err return s3Err
} }
claims, s3Err := getClaimsFromToken(r, cred) claims, s3Err := checkClaimsFromToken(r, cred)
if s3Err != ErrNone { if s3Err != ErrNone {
return s3Err return s3Err
} }

View File

@ -59,7 +59,7 @@ func validateListObjectsArgs(prefix, marker, delimiter string, maxKeys int) APIE
func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "ListObjectsV2") ctx := newContext(r, w, "ListObjectsV2")
defer logger.AuditLog(w, r, "ListObjectsV2") defer logger.AuditLog(w, r, "ListObjectsV2", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -141,7 +141,7 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http
func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "ListObjectsV1") ctx := newContext(r, w, "ListObjectsV1")
defer logger.AuditLog(w, r, "ListObjectsV1") defer logger.AuditLog(w, r, "ListObjectsV1", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]

View File

@ -89,7 +89,7 @@ func initFederatorBackend(objLayer ObjectLayer) {
func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "GetBucketLocation") ctx := newContext(r, w, "GetBucketLocation")
defer logger.AuditLog(w, r, "GetBucketLocation") defer logger.AuditLog(w, r, "GetBucketLocation", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -139,7 +139,7 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *
func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "ListMultipartUploads") ctx := newContext(r, w, "ListMultipartUploads")
defer logger.AuditLog(w, r, "ListMultipartUploads") defer logger.AuditLog(w, r, "ListMultipartUploads", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -192,7 +192,7 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter,
func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "ListBuckets") ctx := newContext(r, w, "ListBuckets")
defer logger.AuditLog(w, r, "ListBuckets") defer logger.AuditLog(w, r, "ListBuckets", mustGetClaimsFromToken(r))
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -250,7 +250,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R
func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "DeleteMultipleObjects") ctx := newContext(r, w, "DeleteMultipleObjects")
defer logger.AuditLog(w, r, "DeleteMultipleObjects") defer logger.AuditLog(w, r, "DeleteMultipleObjects", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -397,7 +397,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "PutBucket") ctx := newContext(r, w, "PutBucket")
defer logger.AuditLog(w, r, "PutBucket") defer logger.AuditLog(w, r, "PutBucket", mustGetClaimsFromToken(r))
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -475,7 +475,7 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req
func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "PostPolicyBucket") ctx := newContext(r, w, "PostPolicyBucket")
defer logger.AuditLog(w, r, "PostPolicyBucket") defer logger.AuditLog(w, r, "PostPolicyBucket", mustGetClaimsFromToken(r))
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -703,7 +703,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "HeadBucket") ctx := newContext(r, w, "HeadBucket")
defer logger.AuditLog(w, r, "HeadBucket") defer logger.AuditLog(w, r, "HeadBucket", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -735,7 +735,7 @@ func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Re
func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "DeleteBucket") ctx := newContext(r, w, "DeleteBucket")
defer logger.AuditLog(w, r, "DeleteBucket") defer logger.AuditLog(w, r, "DeleteBucket", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]

View File

@ -44,7 +44,7 @@ var errNoSuchNotifications = errors.New("The specified bucket does not have buck
func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "GetBucketNotification") ctx := newContext(r, w, "GetBucketNotification")
defer logger.AuditLog(w, r, "GetBucketNotification") defer logger.AuditLog(w, r, "GetBucketNotification", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucketName := vars["bucket"] bucketName := vars["bucket"]
@ -102,7 +102,7 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter,
func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "PutBucketNotification") ctx := newContext(r, w, "PutBucketNotification")
defer logger.AuditLog(w, r, "PutBucketNotification") defer logger.AuditLog(w, r, "PutBucketNotification", mustGetClaimsFromToken(r))
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -164,7 +164,7 @@ func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter,
func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "ListenBucketNotification") ctx := newContext(r, w, "ListenBucketNotification")
defer logger.AuditLog(w, r, "ListenBucketNotification") defer logger.AuditLog(w, r, "ListenBucketNotification", mustGetClaimsFromToken(r))
// Validate if bucket exists. // Validate if bucket exists.
objAPI := api.ObjectAPI() objAPI := api.ObjectAPI()

View File

@ -40,7 +40,7 @@ const (
func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "PutBucketPolicy") ctx := newContext(r, w, "PutBucketPolicy")
defer logger.AuditLog(w, r, "PutBucketPolicy") defer logger.AuditLog(w, r, "PutBucketPolicy", mustGetClaimsFromToken(r))
objAPI := api.ObjectAPI() objAPI := api.ObjectAPI()
if objAPI == nil { if objAPI == nil {
@ -103,7 +103,7 @@ func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *ht
func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "DeleteBucketPolicy") ctx := newContext(r, w, "DeleteBucketPolicy")
defer logger.AuditLog(w, r, "DeleteBucketPolicy") defer logger.AuditLog(w, r, "DeleteBucketPolicy", mustGetClaimsFromToken(r))
objAPI := api.ObjectAPI() objAPI := api.ObjectAPI()
if objAPI == nil { if objAPI == nil {
@ -141,7 +141,7 @@ func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r
func (api objectAPIHandlers) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "GetBucketPolicy") ctx := newContext(r, w, "GetBucketPolicy")
defer logger.AuditLog(w, r, "GetBucketPolicy") defer logger.AuditLog(w, r, "GetBucketPolicy", mustGetClaimsFromToken(r))
objAPI := api.ObjectAPI() objAPI := api.ObjectAPI()
if objAPI == nil { if objAPI == nil {

View File

@ -55,7 +55,7 @@ func AddAuditTarget(t Target) {
} }
// AuditLog - logs audit logs to all audit targets. // AuditLog - logs audit logs to all audit targets.
func AuditLog(w http.ResponseWriter, r *http.Request, api string) { func AuditLog(w http.ResponseWriter, r *http.Request, api string, reqClaims map[string]interface{}) {
var statusCode int var statusCode int
lrw, ok := w.(*ResponseWriter) lrw, ok := w.(*ResponseWriter)
if ok { if ok {
@ -63,6 +63,6 @@ func AuditLog(w http.ResponseWriter, r *http.Request, api string) {
} }
// Send audit logs only to http targets. // Send audit logs only to http targets.
for _, t := range AuditTargets { for _, t := range AuditTargets {
t.Send(audit.ToEntry(w, r, api, statusCode)) _ = t.Send(audit.ToEntry(w, r, api, statusCode, reqClaims))
} }
} }

View File

@ -40,16 +40,17 @@ type Entry struct {
Status string `json:"status,omitempty"` Status string `json:"status,omitempty"`
StatusCode int `json:"statusCode,omitempty"` StatusCode int `json:"statusCode,omitempty"`
} `json:"api"` } `json:"api"`
RemoteHost string `json:"remotehost,omitempty"` RemoteHost string `json:"remotehost,omitempty"`
RequestID string `json:"requestID,omitempty"` RequestID string `json:"requestID,omitempty"`
UserAgent string `json:"userAgent,omitempty"` UserAgent string `json:"userAgent,omitempty"`
ReqQuery map[string]string `json:"requestQuery,omitempty"` ReqClaims map[string]interface{} `json:"requestClaims,omitempty"`
ReqHeader map[string]string `json:"requestHeader,omitempty"` ReqQuery map[string]string `json:"requestQuery,omitempty"`
RespHeader map[string]string `json:"responseHeader,omitempty"` ReqHeader map[string]string `json:"requestHeader,omitempty"`
RespHeader map[string]string `json:"responseHeader,omitempty"`
} }
// ToEntry - constructs an audit entry object. // ToEntry - constructs an audit entry object.
func ToEntry(w http.ResponseWriter, r *http.Request, api string, statusCode int) Entry { func ToEntry(w http.ResponseWriter, r *http.Request, api string, statusCode int, reqClaims map[string]interface{}) Entry {
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
object := vars["object"] object := vars["object"]
@ -77,6 +78,7 @@ func ToEntry(w http.ResponseWriter, r *http.Request, api string, statusCode int)
Time: time.Now().UTC().Format(time.RFC3339Nano), Time: time.Now().UTC().Format(time.RFC3339Nano),
ReqQuery: reqQuery, ReqQuery: reqQuery,
ReqHeader: reqHeader, ReqHeader: reqHeader,
ReqClaims: reqClaims,
RespHeader: respHeader, RespHeader: respHeader,
} }

View File

@ -79,7 +79,7 @@ func setHeadGetRespHeaders(w http.ResponseWriter, reqParams url.Values) {
func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "SelectObject") ctx := newContext(r, w, "SelectObject")
defer logger.AuditLog(w, r, "SelectObject") defer logger.AuditLog(w, r, "SelectObject", mustGetClaimsFromToken(r))
// Fetch object stat info. // Fetch object stat info.
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
@ -305,7 +305,7 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r
func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "GetObject") ctx := newContext(r, w, "GetObject")
defer logger.AuditLog(w, r, "GetObject") defer logger.AuditLog(w, r, "GetObject", mustGetClaimsFromToken(r))
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -473,7 +473,7 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req
func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "HeadObject") ctx := newContext(r, w, "HeadObject")
defer logger.AuditLog(w, r, "HeadObject") defer logger.AuditLog(w, r, "HeadObject", mustGetClaimsFromToken(r))
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -656,7 +656,7 @@ func getCpObjMetadataFromHeader(ctx context.Context, r *http.Request, userMeta m
func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "CopyObject") ctx := newContext(r, w, "CopyObject")
defer logger.AuditLog(w, r, "CopyObject") defer logger.AuditLog(w, r, "CopyObject", mustGetClaimsFromToken(r))
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -1028,7 +1028,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "PutObject") ctx := newContext(r, w, "PutObject")
defer logger.AuditLog(w, r, "PutObject") defer logger.AuditLog(w, r, "PutObject", mustGetClaimsFromToken(r))
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -1291,7 +1291,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req
func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "NewMultipartUpload") ctx := newContext(r, w, "NewMultipartUpload")
defer logger.AuditLog(w, r, "NewMultipartUpload") defer logger.AuditLog(w, r, "NewMultipartUpload", mustGetClaimsFromToken(r))
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -1388,7 +1388,7 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r
func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "CopyObjectPart") ctx := newContext(r, w, "CopyObjectPart")
defer logger.AuditLog(w, r, "CopyObjectPart") defer logger.AuditLog(w, r, "CopyObjectPart", mustGetClaimsFromToken(r))
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -1632,7 +1632,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt
func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "PutObjectPart") ctx := newContext(r, w, "PutObjectPart")
defer logger.AuditLog(w, r, "PutObjectPart") defer logger.AuditLog(w, r, "PutObjectPart", mustGetClaimsFromToken(r))
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -1883,7 +1883,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http
func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "AbortMultipartUpload") ctx := newContext(r, w, "AbortMultipartUpload")
defer logger.AuditLog(w, r, "AbortMultipartUpload") defer logger.AuditLog(w, r, "AbortMultipartUpload", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -1929,7 +1929,7 @@ func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter,
func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "ListObjectParts") ctx := newContext(r, w, "ListObjectParts")
defer logger.AuditLog(w, r, "ListObjectParts") defer logger.AuditLog(w, r, "ListObjectParts", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -2008,7 +2008,7 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht
func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "CompleteMultipartUpload") ctx := newContext(r, w, "CompleteMultipartUpload")
defer logger.AuditLog(w, r, "CompleteMultipartUpload") defer logger.AuditLog(w, r, "CompleteMultipartUpload", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -2187,7 +2187,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "DeleteObject") ctx := newContext(r, w, "DeleteObject")
defer logger.AuditLog(w, r, "DeleteObject") defer logger.AuditLog(w, r, "DeleteObject", mustGetClaimsFromToken(r))
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]

View File

@ -127,6 +127,8 @@ type ClientGrantsResult struct {
func (sts *stsAPIHandlers) AssumeRoleWithClientGrants(w http.ResponseWriter, r *http.Request) { func (sts *stsAPIHandlers) AssumeRoleWithClientGrants(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "AssumeRoleWithClientGrants") ctx := newContext(r, w, "AssumeRoleWithClientGrants")
defer logger.AuditLog(w, r, "AssumeRoleWithClientGrants", nil)
if globalIAMValidators == nil { if globalIAMValidators == nil {
writeSTSErrorResponse(w, ErrSTSNotInitialized) writeSTSErrorResponse(w, ErrSTSNotInitialized)
return return

View File

@ -707,7 +707,7 @@ func (web *webAPIHandlers) CreateURLToken(r *http.Request, args *WebGenericArgs,
func (web *webAPIHandlers) Upload(w http.ResponseWriter, r *http.Request) { func (web *webAPIHandlers) Upload(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "WebUpload") ctx := newContext(r, w, "WebUpload")
defer logger.AuditLog(w, r, "WebUpload") defer logger.AuditLog(w, r, "WebUpload", mustGetClaimsFromToken(r))
objectAPI := web.ObjectAPI() objectAPI := web.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -845,7 +845,7 @@ func (web *webAPIHandlers) Upload(w http.ResponseWriter, r *http.Request) {
func (web *webAPIHandlers) Download(w http.ResponseWriter, r *http.Request) { func (web *webAPIHandlers) Download(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "WebDownload") ctx := newContext(r, w, "WebDownload")
defer logger.AuditLog(w, r, "WebDownload") defer logger.AuditLog(w, r, "WebDownload", mustGetClaimsFromToken(r))
var wg sync.WaitGroup var wg sync.WaitGroup
objectAPI := web.ObjectAPI() objectAPI := web.ObjectAPI()
@ -1027,7 +1027,7 @@ func (web *webAPIHandlers) DownloadZip(w http.ResponseWriter, r *http.Request) {
} }
ctx := newContext(r, w, "WebDownloadZip") ctx := newContext(r, w, "WebDownloadZip")
defer logger.AuditLog(w, r, "WebDownloadZip") defer logger.AuditLog(w, r, "WebDownloadZip", mustGetClaimsFromToken(r))
var wg sync.WaitGroup var wg sync.WaitGroup
objectAPI := web.ObjectAPI() objectAPI := web.ObjectAPI()

View File

@ -77,27 +77,45 @@ Setting this environment variable automatically enables audit logging to the HTT
{ {
"version": "1", "version": "1",
"deploymentid": "1b3002bf-5005-4d9b-853e-64a05008ebb2", "deploymentid": "1b3002bf-5005-4d9b-853e-64a05008ebb2",
"time": "2018-11-02T21:57:58.231480177Z", "time": "2018-11-21T23:16:06.828154172Z",
"api": { "api": {
"name": "ListBuckets", "name": "PutObject",
"args": {} "bucket": "my-bucketname",
"object": "my-objectname",
"status": "OK",
"statusCode": 200
}, },
"remotehost": "127.0.0.1", "remotehost": "127.0.0.1",
"requestID": "15636D7C53428FD4", "requestID": "156946C6C1E7842C",
"userAgent": "Minio (linux; amd64) minio-go/v6.0.8 mc/2018-11-02T21:13:30Z", "userAgent": "Minio (linux; amd64) minio-go/v6.0.6",
"requestClaims": {
"accessKey": "A1YABB5YPX3ZPL4227XJ",
"aud": "PoEgXP6uVO45IsENRngDXj5Au5Ya",
"azp": "PoEgXP6uVO45IsENRngDXj5Au5Ya",
"exp": 1542845766,
"iat": 1542842166,
"iss": "https://localhost:9443/oauth2/token",
"jti": "33527fcc-254f-43d2-a558-4942554b8ff8"
},
"requestHeader": { "requestHeader": {
"Authorization": "AWS4-HMAC-SHA256 Credential=minio/20181102/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=6db486b42a85b23bffba66d654ce60242a7e92fb27cd4a1756e68082c02cc204", "Authorization": "AWS4-HMAC-SHA256 Credential=A1YABB5YPX3ZPL4227XJ/20181121/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-security-token,Signature=689d9b8f67b5625ea2f0b8cbb3f777d8839a91d50aa81e6a5555f5a6360c1714",
"User-Agent": "Minio (linux; amd64) minio-go/v6.0.8 mc/2018-11-02T21:13:30Z", "Content-Length": "184",
"X-Amz-Content-Sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "Content-Type": "application/octet-stream",
"X-Amz-Date": "20181102T215758Z" "User-Agent": "Minio (linux; amd64) minio-go/v6.0.6",
"X-Amz-Content-Sha256": "STREAMING-AWS4-HMAC-SHA256-PAYLOAD",
"X-Amz-Date": "20181121T231606Z",
"X-Amz-Decoded-Content-Length": "12",
"X-Amz-Security-Token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiJBMVlBQkI1WVBYM1pQTDQyMjdYSiIsImF1ZCI6IlBvRWdYUDZ1Vk80NUlzRU5SbmdEWGo1QXU1WWEiLCJhenAiOiJQb0VnWFA2dVZPNDVJc0VOUm5nRFhqNUF1NVlhIiwiZXhwIjoxNTQyODQ1NzY2LCJpYXQiOjE1NDI4NDIxNjYsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0Ojk0NDMvb2F1dGgyL3Rva2VuIiwianRpIjoiMzM1MjdmY2MtMjU0Zi00M2QyLWE1NTgtNDk0MjU1NGI4ZmY4In0.KEuAq2cQ3H7dfIB5DVuvcgBXT38mr0gthrIbVRSZcA2OWo8QiH1-DWXj9xYbndgr1p2tiEUsQ49cuszQGEVGMQ"
}, },
"responseHeader": { "responseHeader": {
"Accept-Ranges": "bytes", "Accept-Ranges": "bytes",
"Content-Security-Policy": "block-all-mixed-content", "Content-Security-Policy": "block-all-mixed-content",
"Content-Type": "application/xml", "Content-Type": "application/xml",
"Server": "Minio/DEVELOPMENT.2018-11-02T21-57-15Z (linux; amd64)", "Etag": "",
"Server": "Minio/DEVELOPMENT.2018-11-21T23-15-06Z (linux; amd64)",
"Vary": "Origin", "Vary": "Origin",
"X-Amz-Request-Id": "15636D7C53428FD4", "X-Amz-Request-Id": "156946C6C1E7842C",
"X-Minio-Deployment-Id": "1b3002bf-5005-4d9b-853e-64a05008ebb2",
"X-Xss-Protection": "1; mode=block" "X-Xss-Protection": "1; mode=block"
} }
} }