0

J'essaie d'obtenir un jeton oauth2 pour mon compte de service en utilisant nodejs. Je suis la documentation trouvée ici:Nodejs post demande d'obtenir un jeton oauth2 pour un compte de service

https://developers.google.com/identity/protocols/OAuth2ServiceAccount#makingrequest

Bien qu'il n'y ait pas un exemple de nœud que j'ai regardé la documentation HTTP/Reste à avoir une idée approximative de ce qu'il attend lors d'une demande de un jeton. Cependant, la réponse que je reçois est la suivante:

Signature JWT non valide. En guise d'aperçu général, lors du calcul de la signature, vous prenez la valeur codée base64url pour l'en-tête et la réclamation, la hachez avec sha256 et la clé privée de la console du développeur google, puis base64url code cette valeur.

Ma tête est:

var header = {"alg":"RS256","typ":"JWT"} 
    var encodedHeader = base64url(new Buffer(header).toString('utf8')); 

La documentation ci-dessus indique même que cette valeur sera après base64url encodant:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9 

Et quand je sortie ma valeur encodedHeader:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9 

Ah excellent il correspond. Donc, il ne devrait pas y avoir un problème d'encodage 64burl pour les autres valeurs. Suivant est la revendication:

var claim ={"aud":"https://www.googleapis.com/oauth2/v4/token","scope":"https://www.googleapis.com/auth/gmail.send","iss":"*****censoredvalue*****gserviceaccount.com","exp":1505399833,"iat":1505396233} 

Il passe par le même processus et est codé (Impossible de montrer pour des raisons de sécurité).

var encodedClaim = base64url(new Buffer(claim).toString('utf8')); 

Pour l'instant, j'utilise des sites tiers pour calculer la signature à des fins de test, mais l'entrée est encodedHeader.encodedClaim + clé privée (valeur étant: ----- BEGIN CLE PRIVEE ....) et en utilisant SHA256. Je vais ensuite prendre cette sortie et b64url l'encoder.

J'ai maintenant une JWT qui est encodedHeader.encodedClaim.encodedSignature

var encoded_jwt = encodedHeader + '.' + encodedClaim + '.' + encodedSignature; 

Je vais faire une demande au point final jeton avec les éléments suivants:

// Set the headers 
    var headers = { 
     'HTTP-Version': 'HTTP/1.1', 
     'Content-Type': 'application/x-www-form-urlencoded' 
    } 

    var bodyOptions = { 'grant_type': "urn:ietf:params:oauth:grant-type:jwt-bearer", assertion: encoded_jwt } 

    // Configure the request 
    var options = { 
     url: 'https://www.googleapis.com/oauth2/v4/token', 
     method: 'POST', 
     headers: headers, 
     form: bodyOptions, 
     json: true 
    } 

    // Start the request 
    request(options, function (error, response, body) { 
     if (!error && response.statusCode == 200) { 
      // Print out the response body 
      console.log(body) 
     } 
     else{ 
      context.log(error); 
      context.log(response); 
     } 
    }); 

Et c'est là que je reçois la réponse d'une erreur indiquant que j'ai une signature invalide.

Aucune idée de la raison pour laquelle il s'agit d'une signature non valide. J'ai aussi essayé plusieurs sites générateurs de signature pour être sûr que ce n'était pas un site spécifique mais c'est toujours la même erreur.

Répondre

0

Pour calculer JWS, vous pouvez utiliser crypto module comme ce qui suit:

const privateKey = fs.readFileSync('private.pem', 'utf-8'); 

const signer = crypto.createSign('sha256'); 
signer.update(data); 
const signature = signer.sign(privateKey, 'base64'); 

data est encodedHeader + '.' + encodedClaim

Un exemple complet tiré de google-oauth-library testcase:

"use strict"; 

const crypto = require('crypto'); 
const fs = require('fs'); 

const publicKey = fs.readFileSync('public.pem', 'utf-8'); 
const privateKey = fs.readFileSync('private.pem', 'utf-8'); 

const maxLifetimeSecs = 86400; 
const now = new Date().getTime()/1000; 
const expiry = now + (maxLifetimeSecs/2); 

const idToken = '{' + 
    '"iss":"testissuer",' + 
    '"aud":"testaudience",' + 
    '"azp":"testauthorisedparty",' + 
    '"email_verified":"true",' + 
    '"id":"123456789",' + 
    '"sub":"123456789",' + 
    '"email":"[email protected]",' + 
    '"iat":' + now + ',' + 
    '"exp":' + expiry + '}'; 

const envelope = '{' + 
    '"kid":"keyid",' + 
    '"alg":"RS256"' + 
    '}'; 

let data = new Buffer(envelope).toString('base64') + '.' + 
    new Buffer(idToken).toString('base64'); 

const signer = crypto.createSign('sha256'); 
signer.update(data); 
const signature = signer.sign(privateKey, 'base64'); 

data += '.' + signature; 

console.log(data);