Présentation
Objectif:ce document explique comment utiliser les GoogleCredential pour exécuter l'autorisation OAuth 2.0 avec les services Google. Pour des informations sur les fonctions génériques OAuth 2.0 que nous fournissons, consultez OAuth 2.0 et la bibliothèque cliente Google OAuth pour Java.
Résumé:Pour accéder aux données protégées stockées sur les services Google, utilisez OAuth 2.0 pour l'autorisation Les API Google sont compatibles avec les flux OAuth 2.0 pour différents types d'applications clientes. Dans tous ces flux, l'application cliente demande un jeton d'accès associée uniquement à votre application cliente et au propriétaire des données protégées en cours d'accès. Le jeton d'accès est également associé à un champ d'application limité qui définit le type de données auxquelles votre application cliente a accès (par exemple, "Gérer vos tâches"). L'un des principaux objectifs d'OAuth 2.0 est de fournir un accès pratique aux données protégées, tout en minimisant l'impact potentiel en cas de vol de jeton d'accès.
Les packages OAuth 2.0 de la bibliothèque cliente des API Google pour Java reposent sur l'objectif général Bibliothèque cliente Google OAuth 2.0 pour Java.
Pour en savoir plus, consultez la documentation Javadoc pour les packages suivants:
- com.google.api.client.googleapis.auth.oauth2 (de google-api-client)
- com.google.api.client.googleapis.extensions.appengine.auth.oauth2 (à partir de google-api-client-appengine)
Console Google APIs
Avant de pouvoir accéder aux API Google, vous devez configurer un projet sur le Console Google APIs pour l'authentification et la facturation qu'il s'agisse d'une application installée, d'une application mobile, un serveur web ou un client qui s'exécute dans un navigateur.
Pour savoir comment configurer correctement vos identifiants, consultez le Aide de la console APIs
Identifiant
GoogleCredential
GoogleCredential est une classe d'assistance sécurisée pour OAuth 2.0 qui permet d'accéder aux ressources protégées à l'aide d'un jeton d'accès. Par exemple, si vous disposez déjà d'un jeton d'accès, peut effectuer une demande de la manière suivante:
GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken); Plus plus = new Plus.builder(new NetHttpTransport(), GsonFactory.getDefaultInstance(), credential) .setApplicationName("Google-PlusSample/1.0") .build();
Identité Google App Engine
Ce certificat alternatif est basé sur le API Java App Identity de Google App Engine Contrairement aux identifiants dans lesquels une application cliente demande l'accès données de l'utilisateur final, l'API App Identity donne accès au client les propres données de l'application.
Utiliser AppIdentityCredential (à partir de google-api-client-appengine). Cet identifiant est beaucoup plus simple, car Google App Engine se charge de toutes les détails. Vous ne devez spécifier que le champ d'application OAuth 2.0 dont vous avez besoin.
Exemple de code issu de urlshortener-robots-appengine-sample:
static Urlshortener newUrlshortener() { AppIdentityCredential credential = new AppIdentityCredential( Collections.singletonList(UrlshortenerScopes.URLSHORTENER)); return new Urlshortener.Builder(new UrlFetchTransport(), GsonFactory.getDefaultInstance(), credential) .build(); }
Datastore
La date d'expiration d'un jeton d'accès est généralement d'une heure. Passé ce délai, vous
un message d'erreur s'affiche
si vous essayez de l'utiliser.
GoogleCredential
se charge de l'actualisation automatique le jeton, c'est-à-dire obtenir
un nouveau jeton d'accès. Cela se fait au moyen d'un jeton d'actualisation de longue durée,
est généralement reçu avec le jeton d'accès si vous utilisez
le paramètre access_type=offline
pendant le flux de code d'autorisation (voir
GoogleAuthorizationCodeFlow.Builder.setAccessType(String)).
La plupart des applications devront conserver le jeton d'accès des identifiants et/ou d'actualisation. Pour conserver les jetons d'accès et/ou d'actualisation des identifiants, vous pouvez fournir votre propre implémentation de DataStoreFactory ; avec StoredCredential ; Vous pouvez également utiliser l'une des implémentations suivantes fournies par la bibliothèque:
- AppEngineDataStoreFactory: conserve l'identifiant à l'aide de l'API Google App Engine Data Store.
- MemoryDataStoreFactory: "persiste" les identifiants en mémoire, qui n'est utile que comme stockage à court terme pendant la durée de vie du processus.
- FileDataStoreFactory: conserve l'identifiant dans un fichier.
Utilisateurs d'App Engine: AppEngineCredentialStore est obsolète et sera bientôt supprimée. Nous vous recommandons d'utiliser AppEngineDataStoreFactory avec StoredCredential. Si vous aviez des informations d'identification stockées à l'ancienne, vous pouvez utiliser les identifiants ajoutés méthodes d'assistance migrateTo(AppEngineDataStoreFactory) ou migrateTo(DataStore) pour effectuer la migration.
Vous pouvez utiliser DataStoreCredentialRefreshListener et le définir pour l'identifiant à l'aide de GoogleCredential.Builder.addRefreshListener(CredentialRefreshListener)).
Flux avec code d'autorisation
Utiliser le flux avec code d'autorisation pour permettre à l'utilisateur final d'accorder à votre application l'accès à leurs données protégées sur les API Google. Le protocole de ce flux est spécifié dans Octroi du code d'autorisation.
Ce flux est mis en œuvre à l'aide de GoogleAuthorizationCodeFlow. Voici la procédure à suivre :
- L'utilisateur final se connecte à votre application. Vous devez associer cet utilisateur avec un ID utilisateur propre à votre application.
- Appelez AuthorizationCodeFlow.loadCredential(String)) en fonction de l'ID utilisateur pour vérifier si les identifiants de l'utilisateur final sont déjà connus. Si c'est le cas, nous avons terminé.
- Si ce n'est pas le cas, appelez AuthorizationCodeFlow.newAuthorizationUrl() et redirigez le navigateur de l'utilisateur final vers une page d'autorisation l'accès des applications à leurs données protégées.
- Le serveur d'autorisation Google redirige alors le navigateur vers
de redirection spécifiée par votre application, accompagnée d'une requête
code
. . Utilisez le paramètrecode
pour demander un jeton d'accès à l'aide du AuthorizationCodeFlow.newTokenRequest(String)). - Utilisez AuthorizationCodeFlow.createAndStoreCredential(TokenResponse, String)). pour stocker et obtenir des identifiants permettant d'accéder aux ressources protégées.
Si vous n'utilisez pas GoogleAuthorizationCodeFlow, vous pouvez également utiliser les classes de niveau inférieur:
- Utilisez DataStore.get(String) pour charger les identifiants à partir du magasin en fonction de l'ID utilisateur.
- Utilisez GoogleAuthorizationCodeRequestUrl pour diriger le navigateur vers la page d'autorisation.
- Utilisez AuthorizationCodeResponseUrl pour traiter la réponse d'autorisation et analyser le code d'autorisation.
- Demandez un jeton d'accès et éventuellement un jeton d'actualisation à l'aide de GoogleAuthorizationCodeTokenRequest.
- Créez un GoogleCredential et stockez-le à l'aide de DataStore.set(String, V).
- Accédez aux ressources protégées à l'aide de
GoogleCredential
. Les jetons d'accès expirés sont automatiquement actualisés à l'aide du jeton d'actualisation (le cas échéant). Veillez à utiliser DataStoreCredentialRefreshListener et à le définir pour l'identifiant à l'aide de GoogleCredential.Builder.addRefreshListener(CredentialRefreshListener).
Lorsque vous configurez votre projet dans la console Google APIs, vous pouvez choisir parmi différents identifiants, selon le flux que vous utilisez. Pour en savoir plus, consultez Configurer OAuth 2.0. et les scénarios OAuth 2.0. Vous trouverez ci-dessous des extraits de code pour chacun des flux.
Applications de serveur Web
Le protocole de ce flux est expliqué dans Utiliser OAuth 2.0 pour les applications de serveur Web
Cette bibliothèque fournit des classes d'assistance de servlet pour simplifier considérablement pour les cas d'utilisation de base. Il suffit de fournir des sous-classes concrètes de AbstractAuthorizationCodeServlet et AbstractAuthorizationCodeCallbackServlet (depuis google-oauth-client-servlet) et ajoutez-les à votre fichier web.xml. Notez que vous devez toujours vous occuper des utilisateurs pour votre application Web afin d'extraire un ID utilisateur.
public class CalendarServletSample extends AbstractAuthorizationCodeServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // do stuff } @Override protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException { GenericUrl url = new GenericUrl(req.getRequestURL().toString()); url.setRawPath("/oauth2callback"); return url.build(); } @Override protected AuthorizationCodeFlow initializeFlow() throws IOException { return new GoogleAuthorizationCodeFlow.Builder( new NetHttpTransport(), GsonFactory.getDefaultInstance(), "[[ENTER YOUR CLIENT ID]]", "[[ENTER YOUR CLIENT SECRET]]", Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory( DATA_STORE_FACTORY).setAccessType("offline").build(); } @Override protected String getUserId(HttpServletRequest req) throws ServletException, IOException { // return user ID } } public class CalendarServletCallbackSample extends AbstractAuthorizationCodeCallbackServlet { @Override protected void onSuccess(HttpServletRequest req, HttpServletResponse resp, Credential credential) throws ServletException, IOException { resp.sendRedirect("/"); } @Override protected void onError( HttpServletRequest req, HttpServletResponse resp, AuthorizationCodeResponseUrl errorResponse) throws ServletException, IOException { // handle error } @Override protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException { GenericUrl url = new GenericUrl(req.getRequestURL().toString()); url.setRawPath("/oauth2callback"); return url.build(); } @Override protected AuthorizationCodeFlow initializeFlow() throws IOException { return new GoogleAuthorizationCodeFlow.Builder( new NetHttpTransport(), GsonFactory.getDefaultInstance() "[[ENTER YOUR CLIENT ID]]", "[[ENTER YOUR CLIENT SECRET]]", Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory( DATA_STORE_FACTORY).setAccessType("offline").build(); } @Override protected String getUserId(HttpServletRequest req) throws ServletException, IOException { // return user ID } }
Applications Google App Engine
Le flux du code d'autorisation sur App Engine est presque identique au servlet. de code d'autorisation, sauf que nous pouvons exploiter API Java Users L'utilisateur doit être connecté pour activer l'API Java Users ; pour obtenir des informations rediriger les utilisateurs vers une page de connexion s'ils ne sont pas déjà connectés, consultez Sécurité et authentification (dans web.xml).
La principale différence par rapport au cas des servlets est que vous fournissez des
sous-classes de
AbstractAppEngineAuthorizationCodeServlet et AbstractAppEngineAuthorizationCodeCallbackServlet
(depuis google-oauth-client-appengine.
Ils étendent les classes de servlet abstraites et implémentent la méthode getUserId
.
à l'aide de l'API Users pour Java. AppEngineDataStoreFactory
(depuis google-http-client-appengine)
est une bonne option pour conserver les identifiants à l'aide de l'API
API Store.
Exemple tiré (légèrement modifié) de calendar-appengine-sample:
public class CalendarAppEngineSample extends AbstractAppEngineAuthorizationCodeServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // do stuff } @Override protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException { return Utils.getRedirectUri(req); } @Override protected AuthorizationCodeFlow initializeFlow() throws IOException { return Utils.newFlow(); } } class Utils { static String getRedirectUri(HttpServletRequest req) { GenericUrl url = new GenericUrl(req.getRequestURL().toString()); url.setRawPath("/oauth2callback"); return url.build(); } static GoogleAuthorizationCodeFlow newFlow() throws IOException { return new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, getClientCredential(), Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory( DATA_STORE_FACTORY).setAccessType("offline").build(); } } public class OAuth2Callback extends AbstractAppEngineAuthorizationCodeCallbackServlet { private static final long serialVersionUID = 1L; @Override protected void onSuccess(HttpServletRequest req, HttpServletResponse resp, Credential credential) throws ServletException, IOException { resp.sendRedirect("/"); } @Override protected void onError( HttpServletRequest req, HttpServletResponse resp, AuthorizationCodeResponseUrl errorResponse) throws ServletException, IOException { String nickname = UserServiceFactory.getUserService().getCurrentUser().getNickname(); resp.getWriter().print("<h3>" + nickname + ", why don't you want to play with me?</h1>"); resp.setStatus(200); resp.addHeader("Content-Type", "text/html"); } @Override protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException { return Utils.getRedirectUri(req); } @Override protected AuthorizationCodeFlow initializeFlow() throws IOException { return Utils.newFlow(); } }
Pour voir un autre exemple, consultez storage-serviceaccount-appengine-sample.
Comptes de service
GoogleCredential est également compatible avec les comptes de service. Contrairement aux identifiants dans lesquels une application cliente demande l'accès données de l'utilisateur final, les comptes de service permettent d'accéder aux applications vos propres données. Votre application cliente signe la demande de jeton d'accès en utilisant Une clé privée téléchargée depuis la console Google APIs
Exemple de code issu de plus-serviceaccount-cmdline-sample:
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport(); JsonFactory jsonFactory = GsonFactory.getDefaultInstance(); ... // Build service account credential. GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json")) .createScoped(Collections.singleton(PlusScopes.PLUS_ME)); // Set up global Plus instance. plus = new Plus.Builder(httpTransport, jsonFactory, credential) .setApplicationName(APPLICATION_NAME).build(); ...
Pour voir un autre exemple, consultez storage-serviceaccount-cmdline-sample.
Usurpation d'identité
Vous pouvez également utiliser le flux de compte de service pour emprunter l'identité d'un utilisateur dans un domaine que vous possédez. Cette procédure est très semblable à celle du compte de service ci-dessus, Appelez également GoogleCredential.Builder.setServiceAccountUser(String).
Applications installées
Il s'agit du flux avec code d'autorisation de ligne de commande décrit dans Utiliser OAuth 2.0 pour les applications installées.
Exemple d'extrait de plus-cmdline-sample:
public static void main(String[] args) { try { httpTransport = GoogleNetHttpTransport.newTrustedTransport(); dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR); // authorization Credential credential = authorize(); // set up global Plus instance plus = new Plus.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName( APPLICATION_NAME).build(); // ... } private static Credential authorize() throws Exception { // load client secrets GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(PlusSample.class.getResourceAsStream("/client_secrets.json"))); // set up authorization code flow GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder( httpTransport, JSON_FACTORY, clientSecrets, Collections.singleton(PlusScopes.PLUS_ME)).setDataStoreFactory( dataStoreFactory).build(); // authorize return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user"); }
Applications côté client
Pour utiliser le flux client intégré au navigateur décrit dans Utiliser OAuth 2.0 pour les applications côté client vous devez généralement procéder comme suit:
- Redirigez l'utilisateur final dans le navigateur vers la page d'autorisation à l'aide de GoogleBrowserClientRequestUrl pour autoriser votre application de navigateur à accéder aux données protégées de l'utilisateur final.
- Utiliser la bibliothèque cliente des API Google pour JavaScript pour traiter le jeton d'accès trouvé dans le fragment d'URL au niveau de l'URI de redirection. dans la console Google APIs.
Exemple d'utilisation pour une application Web:
public void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException { String url = new GoogleBrowserClientRequestUrl("812741506391.apps.googleusercontent.com", "https://oauth2.example.com/oauthcallback", Arrays.asList( "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile")).setState("/profile").build(); response.sendRedirect(url); }
Android
Quelle bibliothèque utiliser avec Android:
Si vous développez pour Android et que l'API Google que vous souhaitez utiliser est incluse dans Bibliothèque des services Google Play pour bénéficier de performances et d'une expérience optimales. Si l'API Google que vous souhaitez utiliser avec Android ne fait pas partie de la bibliothèque des services Google Play, peuvent utiliser la bibliothèque cliente des API Google pour Java, compatible avec Android 4.0 (Ice Cream Sandwich) ; (ou supérieure), et décrit ici. La prise en charge d'Android dans le La bibliothèque cliente des API pour Java est @Beta.
Contexte :
À partir d'Eclair (SDK 2.1), les comptes utilisateur sont gérés sur un appareil Android. à l'aide du gestionnaire de compte. Toutes les autorisations des applications Android sont centralisées gérés par le SDK à l'aide de AccountManager ; Vous spécifiez le champ d'application OAuth 2.0 dont votre application a besoin, et elle renvoie un code d'accès à utiliser.
L'habilitation OAuth 2.0 est spécifiée via le paramètre authTokenType
en tant que oauth2:
.
ainsi que la portée. Exemple :
oauth2:https://www.googleapis.com/auth/tasks
Ce paramètre spécifie l'accès en lecture/écriture à l'API Google Tasks. Si vous avez besoin de plusieurs Pour les champs d'application OAuth 2.0, utilisez une liste séparée par des espaces.
Certaines API disposent de paramètres authTokenType
spéciaux qui fonctionnent également. Par exemple :
"Gérer vos tâches" est un alias pour l'exemple authtokenType
présenté ci-dessus.
Vous devez également spécifier la clé API à partir du Console Google APIs Sinon, le jeton que vous donne le gestionnaire de comptes ne vous fournit que et le quota anonyme, qui est généralement très faible. En revanche, si vous spécifiez une API vous bénéficiez d'un quota sans frais supérieur et pouvez éventuellement configurer la facturation de l'utilisation au-dessus de cela.
Exemple d'extrait de code issu de tasks-android-sample:
com.google.api.services.tasks.Tasks service; @Override public void onCreate(Bundle savedInstanceState) { credential = GoogleAccountCredential.usingOAuth2(this, Collections.singleton(TasksScopes.TASKS)); SharedPreferences settings = getPreferences(Context.MODE_PRIVATE); credential.setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null)); service = new com.google.api.services.tasks.Tasks.Builder(httpTransport, jsonFactory, credential) .setApplicationName("Google-TasksAndroidSample/1.0").build(); } private void chooseAccount() { startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQUEST_GOOGLE_PLAY_SERVICES: if (resultCode == Activity.RESULT_OK) { haveGooglePlayServices(); } else { checkGooglePlayServicesAvailable(); } break; case REQUEST_AUTHORIZATION: if (resultCode == Activity.RESULT_OK) { AsyncLoadTasks.run(this); } else { chooseAccount(); } break; case REQUEST_ACCOUNT_PICKER: if (resultCode == Activity.RESULT_OK && data != null && data.getExtras() != null) { String accountName = data.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME); if (accountName != null) { credential.setSelectedAccountName(accountName); SharedPreferences settings = getPreferences(Context.MODE_PRIVATE); SharedPreferences.Editor editor = settings.edit(); editor.putString(PREF_ACCOUNT_NAME, accountName); editor.commit(); AsyncLoadTasks.run(this); } } break; } }