简体   繁体   中英

Anonymous caller does not have storage.objects.create access but my JWT has scope https://www.googleapis.com/auth/devstorage.full_control

I am following the documentation for server to server OAuth2 flow (creating my own JWT as opposed to using the library).

I've created a service account with the right permissions to upload to my storage bucket. I successfully get an access_token from https://www.googleapis.com/oauth2/v4/token with the scope https://www.googleapis.com/auth/devstorage.full_control as described in documentation and using my service account's email.

When I add the access_token as a header on my POST request as described I get this error message:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "required",
    "message": "Anonymous caller does not have storage.objects.create access to bucket/object.",
    "locationType": "header",
    "location": "Authorization"
   }
  ],
  "code": 401,
  "message": "Anonymous caller does not have storage.objects.create access to bucket/object."
 }
}

This is my JWT structure:

$googleJson = json_decode(file_get_contents('/app/config/jwt/google.json'), true);
        $time = time();
        $headers = [
            'alg' => 'RS256',
            'typ' => 'JWT'
        ];
        $payload = [
            'iss' => $googleJson['client_email'],
            'scope' => 'https://www.googleapis.com/auth/devstorage.full_control'
            'aud' => 'https://www.googleapis.com/oauth2/v4/token',
            'exp' => $time + 120,
            'iat' => $time
        ];
        $jwt = JWTService::create($headers, $payload, $googleJson['private_key']);
        return http_build_query([
            'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
            'assertion' => $jwt
        ]);

What am I missing here? Clearly this access_token should authenticate my request but the error message labelling the request as Anonymous caller makes me dubious that I'm not authenticated at all.

This is the function I use to create the JWT:

public static function create(array $headers, array $payload, string $privateKey): string
    {
        $headers = json_encode($headers);
        $payload = json_encode($payload);

        $base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($headers));
        $base64UrlPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));

        openssl_sign($base64UrlHeader . '.' . $base64UrlPayload, $signature, $privateKey, 'sha256');

        $base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));

        return $base64UrlHeader . '.' . $base64UrlPayload . '.' . $base64UrlSignature;
    }

update: When I include the access token as a query parameter like &access_token=<access_token> it works, so for some reason the access token doesn't work as a header and I can't figure out why

Update2: I was setting the headers as a key value array like

[
   Authorization => Bearer <token>
]

Oops, sorry guys

I was setting the headers as a key value array like

[
   Authorization => Bearer <token>
]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM