Got the credentials for Service Account from Developer Console
First, I converted p12 private key to PEM:
openssl pkcs12 -in
I don't know why, but the problem was with curl
.
I replaced it by WWW::Mechanize:
my $mech = WWW::Mechanize->new( autocheck => 1 );
$mech->post('https://accounts.google.com/o/oauth2/token',
'Content-Type' => 'application/x-www-form-urlencoded',
'Content' => [
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $token_request,
],
);
and it works.
Just in case anybody comes here looking for an approach to obtaining a bearer token from Google Service Account Credentials in the currently provided JSON file; here's a snippet that worked for me after I couldn't use Crypt::JWT or Mojo::JWT::Google.
use LWP::UserAgent;
use JSON;
use Mojo::JWT;
use Mojo::File;
my $jwt = create_jwt_from_path_and_scopes( 'path/to/credentials.json', 'email https://www.googleapis.com/auth/compute' );
my $ua = LWP::UserAgent->new();
my $response = $ua->post('https://www.googleapis.com/oauth2/v4/token',
{ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt
}
);
#######################################################################
sub create_jwt_from_path_and_scopes
{
my ( $path, $scope ) = @_;
croak("No path provided") if not defined $path;
croak("$path no available") if not -f $path;
my $json = decode_json( Mojo::File->new($path)->slurp );
croak("No Private key in $path") if not defined $json->{private_key};
croak("Not a service account") if $json->{type} ne 'service_account';
my $jwt = Mojo::JWT->new();
$jwt->algorithm('RS256');
$jwt->secret($json->{private_key});
$jwt->claims( {
iss => $json->{client_email},
scope => $scope,
aud => 'https://www.googleapis.com/oauth2/v4/token',
iat => time(),
exp => time()+3600
} );
$jwt->set_iat( 1 );
return $jwt->encode;
}
#######################################################################
Change your curl command to be:
curl -H "Content-Type: application/x-www-form-urlencoded" \
-d grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \
-d assertion=$token_request \
https://accounts.google.com/oauth2/token
Try to use BASE64URL instead of BASE64. JWT/JWS/JWE specifications use BASE64URL.
MIME::Base64 ---> MIME::Base64::URLSafe
encode_base64 ---> urlsafe_b64encode