Using OAuth 2.0 with the Google API Client Library for Java

Overview

Purpose: This document explains how to use theGoogleCredentialutility class to do OAuth 2.0 authorization with Google services. Forinformation about the generic OAuth 2.0 functions that we provide, seeOAuth 2.0 and the Google OAuth Client Library for Java.

Summary: To access protected data stored on Google services, useOAuth 2.0 for authorization.Google APIs support OAuth 2.0 flows for different types of client applications.In all of these flows, the client application requests an access token that isassociated with only your client application and the owner of the protected databeing accessed. The access token is also associated with a limited scope thatdefines the kind of data your client application has access to (for example"Manage your tasks"). An important goal for OAuth 2.0 is to provide secure andconvenient access to the protected data, while minimizing the potential impactif an access token is stolen.

The OAuth 2.0 packages in the Google API Client Library for Java are built onthe general-purposeGoogle OAuth 2.0 Client Library for Java.

For details, see the Javadoc documentation for the following packages:

Google API Console

Before you can access Google APIs, you need to set up a project on theGoogle API Console for auth and billingpurposes, whether your client is an installed application, a mobile application,a web server, or a client that runs in browser.

For instructions on setting up your credentials properly, see theAPI Console Help.

Credential

GoogleCredential

GoogleCredentialis a thread-safe helper class for OAuth 2.0 for accessing protected resourcesusing an access token. For example, if you already have an access token, youcan make a request in the following way:

GoogleCredentialcredential=newGoogleCredential().setAccessToken(accessToken);Plusplus=newPlus.builder(newNetHttpTransport(),GsonFactory.getDefaultInstance(),credential).setApplicationName("Google-PlusSample/1.0").build();

Google App Engine identity

This alternative credential is based on theGoogle App Engine App Identity Java API.Unlike the credential in which a client application requests access to anend-user's data, the App Identity API provides access to the clientapplication's own data.

UseAppIdentityCredential(fromgoogle-api-client-appengine).This credential is much simpler because Google App Engine takes care of all ofthe details. You only specify the OAuth 2.0 scope you need.

Example code taken fromurlshortener-robots-appengine-sample:

staticUrlshortenernewUrlshortener(){AppIdentityCredentialcredential=newAppIdentityCredential(Collections.singletonList(UrlshortenerScopes.URLSHORTENER));returnnewUrlshortener.Builder(newUrlFetchTransport(),GsonFactory.getDefaultInstance(),credential).build();}

Data store

An access token typically has an expiration date of 1 hour, after which you willget an error if you try to use it.GoogleCredentialtakes care of automatically "refreshing" the token, which simply means gettinga new access token. This is done by means of a long-lived refresh token, whichis typically received along with the access token if you use theaccess_type=offline parameter during the authorization code flow (seeGoogleAuthorizationCodeFlow.Builder.setAccessType(String)).

Most applications will need to persist the credential's access token and/orrefresh token. To persist the credential's access and/or refresh tokens, you canprovide your own implementation ofDataStoreFactorywithStoredCredential;or you can use one of the following implementations provided by the library:

AppEngine Users:AppEngineCredentialStore is deprecated and will be removed soon. We recommend that you useAppEngineDataStoreFactory withStoredCredential. If you have credentials stored in the old fashion, you can use the added helper methodsmigrateTo(AppEngineDataStoreFactory) ormigrateTo(DataStore) to do the migration.

You may useDataStoreCredentialRefreshListenerand set it for the credential usingGoogleCredential.Builder.addRefreshListener(CredentialRefreshListener)).

Authorization code flow

Use the authorization code flow to allow the end-user to grant your applicationaccess to their protected data on Google APIs. The protocol for this flow isspecified inAuthorization Code Grant.

This flow is implemented usingGoogleAuthorizationCodeFlow.The steps are:

Alternatively, if you are not usingGoogleAuthorizationCodeFlow, you may use the lower-level classes:

When you set up your project in theGoogle API Console,you select among different credentials, depending on the flow you are using.For more details, seeSetting up OAuth 2.0andOAuth 2.0 Scenarios.Code snippets for each of the flows are below.

Web server applications

The protocol for this flow is explained inUsing OAuth 2.0 for Web Server Applications.

This library provides servlet helper classes to significantly simplify theauthorization code flow for basic use cases. You just provide concrete subclassesofAbstractAuthorizationCodeServletandAbstractAuthorizationCodeCallbackServlet(fromgoogle-oauth-client-servlet)and add them to your web.xml file. Note that you still need to take care of userlogin for your web application and extract a user ID.

publicclassCalendarServletSampleextendsAbstractAuthorizationCodeServlet{@OverrideprotectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{// do stuff}@OverrideprotectedStringgetRedirectUri(HttpServletRequestreq)throwsServletException,IOException{GenericUrlurl=newGenericUrl(req.getRequestURL().toString());url.setRawPath("/oauth2callback");returnurl.build();}@OverrideprotectedAuthorizationCodeFlowinitializeFlow()throwsIOException{returnnewGoogleAuthorizationCodeFlow.Builder(newNetHttpTransport(),GsonFactory.getDefaultInstance(),"[[ENTER YOUR CLIENT ID]]","[[ENTER YOUR CLIENT SECRET]]",Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(DATA_STORE_FACTORY).setAccessType("offline").build();}@OverrideprotectedStringgetUserId(HttpServletRequestreq)throwsServletException,IOException{// return user ID}}publicclassCalendarServletCallbackSampleextendsAbstractAuthorizationCodeCallbackServlet{@OverrideprotectedvoidonSuccess(HttpServletRequestreq,HttpServletResponseresp,Credentialcredential)throwsServletException,IOException{resp.sendRedirect("/");}@OverrideprotectedvoidonError(HttpServletRequestreq,HttpServletResponseresp,AuthorizationCodeResponseUrlerrorResponse)throwsServletException,IOException{// handle error}@OverrideprotectedStringgetRedirectUri(HttpServletRequestreq)throwsServletException,IOException{GenericUrlurl=newGenericUrl(req.getRequestURL().toString());url.setRawPath("/oauth2callback");returnurl.build();}@OverrideprotectedAuthorizationCodeFlowinitializeFlow()throwsIOException{returnnewGoogleAuthorizationCodeFlow.Builder(newNetHttpTransport(),GsonFactory.getDefaultInstance()"[[ENTER YOUR CLIENT ID]]","[[ENTER YOUR CLIENT SECRET]]",Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(DATA_STORE_FACTORY).setAccessType("offline").build();}@OverrideprotectedStringgetUserId(HttpServletRequestreq)throwsServletException,IOException{// return user ID}}

Google App Engine applications

The authorization code flow on App Engine is almost identical to the servletauthorization code flow, except that we can leverage Google App Engine'sUsers Java API. The userneeds to be logged in for the Users Java API to be enabled; for information aboutredirecting users to a login page if they are not already logged in, seeSecurity and Authentication(in web.xml).

The primary difference from the servlet case is that you provide concretesubclasses ofAbstractAppEngineAuthorizationCodeServlet andAbstractAppEngineAuthorizationCodeCallbackServlet(fromgoogle-oauth-client-appengine.They extend the abstract servlet classes and implement thegetUserId methodfor you using the Users Java API.AppEngineDataStoreFactory(fromgoogle-http-client-appengine)is a good option for persisting the credential using the Google App Engine DataStore API.

Example taken (slightly modified) fromcalendar-appengine-sample:

publicclassCalendarAppEngineSampleextendsAbstractAppEngineAuthorizationCodeServlet{@OverrideprotectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{// do stuff}@OverrideprotectedStringgetRedirectUri(HttpServletRequestreq)throwsServletException,IOException{returnUtils.getRedirectUri(req);}@OverrideprotectedAuthorizationCodeFlowinitializeFlow()throwsIOException{returnUtils.newFlow();}}classUtils{staticStringgetRedirectUri(HttpServletRequestreq){GenericUrlurl=newGenericUrl(req.getRequestURL().toString());url.setRawPath("/oauth2callback");returnurl.build();}staticGoogleAuthorizationCodeFlownewFlow()throwsIOException{returnnewGoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT,JSON_FACTORY,getClientCredential(),Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(DATA_STORE_FACTORY).setAccessType("offline").build();}}publicclassOAuth2CallbackextendsAbstractAppEngineAuthorizationCodeCallbackServlet{privatestaticfinallongserialVersionUID=1L;@OverrideprotectedvoidonSuccess(HttpServletRequestreq,HttpServletResponseresp,Credentialcredential)throwsServletException,IOException{resp.sendRedirect("/");}@OverrideprotectedvoidonError(HttpServletRequestreq,HttpServletResponseresp,AuthorizationCodeResponseUrlerrorResponse)throwsServletException,IOException{Stringnickname=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");}@OverrideprotectedStringgetRedirectUri(HttpServletRequestreq)throwsServletException,IOException{returnUtils.getRedirectUri(req);}@OverrideprotectedAuthorizationCodeFlowinitializeFlow()throwsIOException{returnUtils.newFlow();}}

For an additional sample, seestorage-serviceaccount-appengine-sample.

Service accounts

GoogleCredentialalso supportsservice accounts.Unlike the credential in which a client application requests access to anend-user's data, Service Accounts provide access to the client application'sown data. Your client application signs the request for an access token usinga private key downloaded from theGoogle API Console.

Example code taken fromplus-serviceaccount-cmdline-sample:

HttpTransporthttpTransport=GoogleNetHttpTransport.newTrustedTransport();JsonFactoryjsonFactory=GsonFactory.getDefaultInstance();...// Build service account credential.GoogleCredentialcredential=GoogleCredential.fromStream(newFileInputStream("MyProject-1234.json")).createScoped(Collections.singleton(PlusScopes.PLUS_ME));// Set up global Plus instance.plus=newPlus.Builder(httpTransport,jsonFactory,credential).setApplicationName(APPLICATION_NAME).build();...

For an additional sample, seestorage-serviceaccount-cmdline-sample.

Note: Although you can use service accountsin applications that run from a Google Apps domain, service accounts are notmembers of your Google Apps account and aren't subject to domain policies set byGoogle Apps administrators. For example, a policy set in the Google Apps adminconsole to restrict the ability of Apps end users to share documents outside ofthe domain would not apply to service accounts.

Impersonation

You can also use the service account flow to impersonate a user in a domain thatyou own. This is very similar to the service account flow above, but youadditionally callGoogleCredential.Builder.setServiceAccountUser(String).

Installed applications

This is the command-line authorization code flow described inUsing OAuth 2.0 for Installed Applications.

Example snippet fromplus-cmdline-sample:

publicstaticvoidmain(String[]args){try{httpTransport=GoogleNetHttpTransport.newTrustedTransport();dataStoreFactory=newFileDataStoreFactory(DATA_STORE_DIR);// authorizationCredentialcredential=authorize();// set up global Plus instanceplus=newPlus.Builder(httpTransport,JSON_FACTORY,credential).setApplicationName(APPLICATION_NAME).build();// ...}privatestaticCredentialauthorize()throwsException{// load client secretsGoogleClientSecretsclientSecrets=GoogleClientSecrets.load(JSON_FACTORY,newInputStreamReader(PlusSample.class.getResourceAsStream("/client_secrets.json")));// set up authorization code flowGoogleAuthorizationCodeFlowflow=newGoogleAuthorizationCodeFlow.Builder(httpTransport,JSON_FACTORY,clientSecrets,Collections.singleton(PlusScopes.PLUS_ME)).setDataStoreFactory(dataStoreFactory).build();// authorizereturnnewAuthorizationCodeInstalledApp(flow,newLocalServerReceiver()).authorize("user");}

Client-side applications

To use the browser-based client flow described inUsing OAuth 2.0 for Client-side Applications,you would typically follow these steps:

  1. Redirect the end user in the browser to the authorization page usingGoogleBrowserClientRequestUrlto grant your browser application access to the end user's protected data.
  2. Use theGoogle API Client Library for JavaScriptto process the access token found in the URL fragment at the redirect URIregistered at theGoogle API Console.

Sample usage for a web application:

publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{Stringurl=newGoogleBrowserClientRequestUrl("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

@Beta

Which library to use with Android:

If you are developing for Android and the Google API you want to use is includedin theGoogle Play Services library,use that library for the best performance and experience. If the Google API youwant to use with Android is not part of the Google Play Services library, youcan use the Google API Client Library for Java, which supports Android 4.0 (Ice Cream Sandwich)(or higher), and which is described here. The support for Android in the GoogleAPI Client Library for Java is@Beta.

Background:

Starting with Eclair (SDK 2.1), user accounts are managed on an Android deviceusing the Account Manager. All Android application authorization is centrallymanaged by the SDK usingAccountManager.You specify the OAuth 2.0 scope your application needs, and it returns an accesstoken to use.

The OAuth 2.0 scope is specified via theauthTokenType parameter asoauth2:plus the scope. For example:

oauth2:https://www.googleapis.com/auth/tasks

This specifies read/write access to the Google Tasks API. If you need multipleOAuth 2.0 scopes, use a space-separated list.

Some APIs have specialauthTokenType parameters that also work. For example,"Manage your tasks" is an alias for theauthtokenType example shown above.

You must also specify the API key from theGoogle API Console.Otherwise, the token that the AccountManager gives you only provides you withanonymous quota, which is usually very low. By contrast, by specifying an APIkey you receive a higher free quota, and can optionally set up billing for usageabove that.

Example code snippet taken fromtasks-android-sample:

com.google.api.services.tasks.Tasksservice;@OverridepublicvoidonCreate(BundlesavedInstanceState){credential=GoogleAccountCredential.usingOAuth2(this,Collections.singleton(TasksScopes.TASKS));SharedPreferencessettings=getPreferences(Context.MODE_PRIVATE);credential.setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME,null));service=newcom.google.api.services.tasks.Tasks.Builder(httpTransport,jsonFactory,credential).setApplicationName("Google-TasksAndroidSample/1.0").build();}privatevoidchooseAccount(){startActivityForResult(credential.newChooseAccountIntent(),REQUEST_ACCOUNT_PICKER);}@OverrideprotectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){super.onActivityResult(requestCode,resultCode,data);switch(requestCode){caseREQUEST_GOOGLE_PLAY_SERVICES:if(resultCode==Activity.RESULT_OK){haveGooglePlayServices();}else{checkGooglePlayServicesAvailable();}break;caseREQUEST_AUTHORIZATION:if(resultCode==Activity.RESULT_OK){AsyncLoadTasks.run(this);}else{chooseAccount();}break;caseREQUEST_ACCOUNT_PICKER:if(resultCode==Activity.RESULT_OK&&data!=null&&data.getExtras()!=null){StringaccountName=data.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME);if(accountName!=null){credential.setSelectedAccountName(accountName);SharedPreferencessettings=getPreferences(Context.MODE_PRIVATE);SharedPreferences.Editoreditor=settings.edit();editor.putString(PREF_ACCOUNT_NAME,accountName);editor.commit();AsyncLoadTasks.run(this);}}break;}}

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-05-07 UTC.