mécanisme général OAuth2 : https://developers.google.com/accounts/docs/OAuth2?hl=fr OAuth2 pour compte de service : https://developers.google.com/accounts/docs/OAuth2ServiceAccount?hl=fr OAuth2 pour ruby :https://developers.google.com/api-client-library/ruby/guide/aaa_oauthLe but de cet article est d'expliquer synthétiquement comme utiliser un compte de service dans un script Ruby pour accéder aux ressources d'un domaine Google Apps. On considère le pré-requis qu'un compte de service a été créé et délégation lui a été donnée sur certains scopes de l'API dans le domaine Google Apps Tout accès à l'API Google se fait après authentification OAuth2. Comme expliqué dans la documentation sur le fonctionnement du compte de service avec OAuth2, le consentement de l'utilisateur dont on manipule les données ne sera pas nécessaire : le compte de service, après authentificaton OAuth va agir directement sur l'API. Cette authentification du compte de service par OAuth2 va nécessiter la création, la signature avec le clé privée et l'échange de jetons (nommés JWT Jason Web Token) entre le script client Ruby utilisant le compte de service et le serveur d'authentification. La gestion manuelle des jetons (création, encodage base64, signature, url_encodage, expiration, etc) étant assez délicate, Google incite fortement les développeurs à utiliser les librairies clientes qu'il fournit dans les principaux langages pour s'abstraire de cette difficulté. citations : Caution: This document is for library developers and platform developers who are comfortable with advanced coding tasks. The mechanics of server-to-server authentication interactions require applications to create and cryptographically sign JSON Web Tokens (JWTs), and it's easy to make serious errors that can have a severe impact on the security of your application. Client librariesWhen at all possible, do not write the logic for creating and signing JWTs. Instead, we strongly encourage you to use libraries that abstract the cryptography away from your application code. Python, PHP, and Java are currently supported in the Google APIs client libraries, and support across more languages is underway.
La librairie est proposée sous la forme d'un gem (https://rubygems.org/gems/google-api-client) donc rien de plus simple à installer : gem install google-api-client À noter que ce gem installera, si ne vous les avez pas déjà, les gems d'authentification OAuth2, ainsi que le gem Signet qui gére tout le mécanisme d'échange des tokens et de l'authentification. Accès à Google AppsIl suffit ensuite simplement de coder l'accès à votre domaine à partir du compte de service.La documentation de Google sur la librairie cliente Ruby omet de préciser que l'accès doit impérativement associer un compte administrateur du domaine (sans que ce dernier ne donne son mot de passe) au compte de service. Ce mécanisme est nommé impersonation (usurpation d'identité): les accès au domaine sont faits avec le compte de service, mais sous le nom de l'administrateur associé. Un accès à l'API avec un compte de service nécessite donc :
Voici un exemple de code inspiré de https://gist.github.com/thomaswitt/7468182 require 'google/api_client' # email du compte de service OAuth2 de l'API SERVICE_ACCOUNT_EMAIL = "b84si5jsf4ndtqnt3@developer.gserviceaccount.com" # email d'un administrateur du domaine ACT_ON_BEHALF_EMAIL = "admin@mondomaine.fr" # chemin du fichier de clé privée du compte de service PKCS12_FILE = "clientKey.p12" # Partie de l'API Google interrogée SCOPE = 'https://www.googleapis.com/auth/admin.directory.user' # instanciation du client key = Google::APIClient::KeyUtils.load_from_pkcs12(PKCS12_FILE, 'notasecret') client = Google::APIClient.new(:application_name => "creation_mails_etudiants", :version => "v0.0.1") # authentification proprement dite client.authorization = Signet::OAuth2::Client.new( :token_credential_uri => 'https://accounts.google.com/o/oauth2/token', :audience => 'https://accounts.google.com/o/oauth2/token', :scope => SCOPE, :issuer => SERVICE_ACCOUNT_EMAIL, :person => ACT_ON_BEHALF_EMAIL, # :person = paramètre contenant le nom d'un administrateur pour l'impersonation ! :signing_key => key) client.authorization.fetch_access_token! # récupération des méthodes publiées par l'API api = client.discovered_api("admin", "directory_v1") # execution d'une méthode, ici : api.users.get avec une valeur du paramètre userKey result = client.execute( :api_method => api.users.get, :parameters => {'userKey' => 'gerard.manvussat@mondomaine.fr'} ) # affichage des résultats users = JSON.parse(result.body, {:symbolize_names => true}) users.each do |u| puts "#{u} " end extrait du wiki github source de la libraire : Service accounts are also used for delegation in Google Apps domains. The target user for impersonation is specified by setting the :person parameter to the user's email address
in the credentials |