diff --git a/cmd/neofs-rest-gw/integration_test.go b/cmd/neofs-rest-gw/integration_test.go index 9795cb7..b36fb1b 100644 --- a/cmd/neofs-rest-gw/integration_test.go +++ b/cmd/neofs-rest-gw/integration_test.go @@ -136,9 +136,11 @@ func runTests(ctx context.Context, t *testing.T, key *keys.PrivateKey, node stri t.Run("rest get object", func(t *testing.T) { restObjectGet(ctx, t, clientPool, &owner, cnrID, signer) }) t.Run("rest get object unauthenticated", func(t *testing.T) { restObjectGetUnauthenticated(ctx, t, clientPool, &owner, cnrID, signer) }) t.Run("rest get object full bearer", func(t *testing.T) { restObjectGetFullBearer(ctx, t, clientPool, &owner, cnrID, signer) }) + t.Run("rest get object with bearer in cookie", func(t *testing.T) { restObjectGetBearerCookie(ctx, t, clientPool, &owner, cnrID, signer) }) t.Run("rest delete object", func(t *testing.T) { restObjectDelete(ctx, t, clientPool, &owner, cnrID, signer) }) t.Run("rest search objects", func(t *testing.T) { restObjectsSearch(ctx, t, clientPool, &owner, cnrID, signer) }) t.Run("rest upload object", func(t *testing.T) { restObjectUpload(ctx, t, clientPool, cnrID, signer) }) + t.Run("rest upload object with bearer in cookie", func(t *testing.T) { restObjectUploadCookie(ctx, t, clientPool, cnrID, signer) }) t.Run("rest head object", func(t *testing.T) { restObjectHead(ctx, t, clientPool, &owner, cnrID, signer) }) t.Run("rest head by attribute", func(t *testing.T) { restObjectHeadByAttribute(ctx, t, clientPool, &owner, cnrID, signer) }) t.Run("rest get by attribute", func(t *testing.T) { restObjectGetByAttribute(ctx, t, clientPool, &owner, cnrID, signer) }) @@ -1084,6 +1086,12 @@ func restObjectGetUnauthenticated(ctx context.Context, t *testing.T, p *pool.Poo } func restObjectGetFullBearer(ctx context.Context, t *testing.T, p *pool.Pool, ownerID *user.ID, cnrID cid.ID, signer user.Signer) { + restObjectGetWithBearer(ctx, t, p, ownerID, cnrID, signer, false) +} +func restObjectGetBearerCookie(ctx context.Context, t *testing.T, p *pool.Pool, ownerID *user.ID, cnrID cid.ID, signer user.Signer) { + restObjectGetWithBearer(ctx, t, p, ownerID, cnrID, signer, true) +} +func restObjectGetWithBearer(ctx context.Context, t *testing.T, p *pool.Pool, ownerID *user.ID, cnrID cid.ID, signer user.Signer, cookie bool) { content := []byte("some content") attributes := map[string]string{ object.AttributeFileName: "get-obj-name", @@ -1140,7 +1148,11 @@ func restObjectGetFullBearer(ctx context.Context, t *testing.T, p *pool.Pool, ow request, err = http.NewRequest(http.MethodGet, testHost+"/v1/objects/"+cnrID.EncodeToString()+"/"+objID.EncodeToString()+"?"+query.Encode(), nil) require.NoError(t, err) - request.Header.Add("Authorization", "Bearer "+resp.Token) + if cookie { + request.Header.Add("Cookie", "Bearer="+resp.Token+";") + } else { + request.Header.Add("Authorization", "Bearer "+resp.Token) + } objInfo := &apiserver.ObjectInfo{} doRequest(t, httpClient, request, http.StatusOK, objInfo) @@ -1767,6 +1779,12 @@ func restBalance(_ context.Context, t *testing.T) { } func restObjectUpload(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID cid.ID, signer user.Signer) { + restObjectUploadInt(ctx, t, clientPool, cnrID, signer, false) +} +func restObjectUploadCookie(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID cid.ID, signer user.Signer) { + restObjectUploadInt(ctx, t, clientPool, cnrID, signer, true) +} +func restObjectUploadInt(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID cid.ID, signer user.Signer, cookie bool) { bt := apiserver.Bearer{ Object: []apiserver.Record{{ Operation: apiserver.OperationPUT, @@ -1817,8 +1835,11 @@ func restObjectUpload(ctx context.Context, t *testing.T, clientPool *pool.Pool, require.NoError(t, err) request.Header.Set("Content-Type", writer.FormDataContentType()) - request.Header.Add("Authorization", "Bearer "+base64.StdEncoding.EncodeToString(actualTokenRaw)) - + if cookie { + request.Header.Add("Cookie", "Bearer="+base64.StdEncoding.EncodeToString(actualTokenRaw)+";") + } else { + request.Header.Add("Authorization", "Bearer "+base64.StdEncoding.EncodeToString(actualTokenRaw)) + } addr := &apiserver.AddressForUpload{} doRequest(t, httpClient, request, http.StatusOK, addr) diff --git a/handlers/api.go b/handlers/api.go index 896d166..cb0bd81 100644 --- a/handlers/api.go +++ b/handlers/api.go @@ -43,9 +43,10 @@ type SessionToken struct { } const ( - // BearerPrefix is the prefix for authorization token. - BearerPrefix = "Bearer " - BearerCookiePrefix = "Bearer=" + // bearerCookieName is the name of the bearer cookie. + bearerCookieName = "Bearer" + // bearerPrefix is the prefix for authorization token. + bearerPrefix = bearerCookieName + " " accessControlAllowOriginHeader = "Access-Control-Allow-Origin" authorizationHeader = "Authorization" @@ -78,11 +79,11 @@ func getPrincipalFromHeader(ctx echo.Context) (string, error) { return "", nil } - if !strings.HasPrefix(headerValue, BearerPrefix) { + if !strings.HasPrefix(headerValue, bearerPrefix) { return "", errors.New("http auth: no bearer token") } - if headerValue = strings.TrimPrefix(headerValue, BearerPrefix); len(headerValue) == 0 { + if headerValue = strings.TrimPrefix(headerValue, bearerPrefix); len(headerValue) == 0 { return "", errors.New("http auth: bearer token is empty") } @@ -90,17 +91,13 @@ func getPrincipalFromHeader(ctx echo.Context) (string, error) { } func getPrincipalFromCookie(ctx echo.Context) (string, error) { - var bearerCookie string - for _, cookie := range ctx.Request().Cookies() { - cookieValue := strings.TrimSpace(cookie.Value) - if strings.HasPrefix(cookieValue, BearerCookiePrefix) { - bearerCookie = strings.TrimPrefix(cookieValue, BearerCookiePrefix) - if len(bearerCookie) == 0 { + if cookie.Name == bearerCookieName { + if len(cookie.Value) == 0 { return "", errors.New("cookie auth: bearer token is empty") } - return bearerCookie, nil + return cookie.Value, nil } } @@ -117,16 +114,7 @@ func getPrincipal(ctx echo.Context) (string, error) { return principal, nil } - principal, err = getPrincipalFromCookie(ctx) - if err != nil { - return "", err - } - - if principal != "" { - return principal, nil - } - - return "", nil + return getPrincipalFromCookie(ctx) } func (a *RestAPI) logAndGetErrorResponse(msg string, err error, fields ...zap.Field) *apiserver.ErrorResponse {