Übersicht
Zweck:In diesem Dokument wird die Verwendung des GoogleCredential Dienstprogrammklasse für die OAuth 2.0-Autorisierung für Google-Dienste. Für Informationen zu den von uns bereitgestellten generischen OAuth 2.0-Funktionen finden Sie unter OAuth 2.0 und die Google OAuth-Clientbibliothek für Java
Zusammenfassung:Wenn Sie auf geschützte Daten zugreifen möchten, die in Google-Diensten gespeichert sind, verwenden Sie OAuth 2.0 für die Autorisierung. Google APIs unterstützen OAuth 2.0-Abläufe für verschiedene Arten von Clientanwendungen. Bei all diesen Abläufen fordert die Client-Anwendung ein Zugriffstoken an, die nur mit Ihrer Clientanwendung und dem Eigentümer der geschützten Daten verknüpft sind, auf die zugegriffen wird. Das Zugriffstoken ist außerdem einem eingeschränkten Bereich zugeordnet, definiert die Art der Daten, auf die Ihre Clientanwendung zugreifen kann (z. B. „Aufgaben verwalten“). Ein wichtiges Ziel für OAuth 2.0 ist es, sichere und bequemen Zugriff auf die geschützten Daten zu ermöglichen und gleichzeitig die potenziellen Auswirkungen zu minimieren. wenn ein Zugriffstoken gestohlen wird.
Die OAuth 2.0-Pakete in der Google API-Clientbibliothek für Java basieren auf für allgemeine Zwecke Google OAuth 2.0-Clientbibliothek für Java
Weitere Informationen finden Sie in der Javadoc-Dokumentation für die folgenden Pakete:
- com.google.api.client.googleapis.auth.oauth2 (von google-api-client)
- com.google.api.client.googleapis.extensions.appengine.auth.oauth2 (von google-api-client-appengine)
Google API-Konsole
Bevor Sie auf Google APIs zugreifen können, müssen Sie ein Projekt auf der Google API Console für Authentifizierung und Abrechnung ob es sich bei Ihrem Client um eine installierte App, eine mobile App Webserver oder Client, der im Browser ausgeführt wird.
Eine Anleitung zum ordnungsgemäßen Einrichten Ihrer Anmeldedaten finden Sie auf der Hilfe zur API Console
Anmeldedaten
GoogleCredential
GoogleCredential ist eine threadsichere Hilfsklasse für OAuth 2.0 für den Zugriff auf geschützte Ressourcen mithilfe eines Zugriffstokens. Wenn Sie beispielsweise bereits ein Zugriffstoken haben, wie folgt eine Anfrage stellen:
GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken); Plus plus = new Plus.builder(new NetHttpTransport(), GsonFactory.getDefaultInstance(), credential) .setApplicationName("Google-PlusSample/1.0") .build();
Google App Engine-Identität
Diese alternativen Anmeldedaten basieren auf dem Google App Engine App Identity Java API Im Gegensatz zu den Anmeldedaten, mit denen eine Client-Anwendung Zugriff auf einen Endnutzerdaten enthält, bietet die App Identity API Zugriff auf den Client Daten der Anwendung nutzen.
AppIdentityCredential verwenden (von google-api-client-appengine). Diese Anmeldedaten sind viel einfacher, da Google App Engine alle zu den Details. Sie geben nur den benötigten OAuth 2.0-Bereich an.
Beispielcode von 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(); }
Datenspeicher
Zugriffs-Tokens laufen in der Regel nach einer Stunde ab. Danach werden Sie
erhalten Sie eine Fehlermeldung,
wenn Sie versuchen, es zu verwenden.
GoogleCredential
sorgt dafür, dass die Seite das Token, was einfach bedeutet,
ein neues Zugriffstoken. Dies erfolgt über ein langlebiges Aktualisierungstoken, das
wird normalerweise zusammen mit dem Zugriffstoken empfangen, wenn Sie die Methode
access_type=offline
während des Autorisierungscode-Vorgangs (siehe
GoogleAuthorizationCodeFlow.Builder.setAccessType(String) verwendet wird.
Die meisten Anwendungen müssen das Zugriffstoken der Anmeldedaten persistieren und/oder Aktualisierungstoken. Um das Zugriffs- und/oder Aktualisierungstoken der Anmeldedaten beizubehalten, können Sie Ihre eigene Implementierung von DataStoreFactory bereitstellen mit StoredCredential Alternativ können Sie eine der folgenden von der Bibliothek bereitgestellten Implementierungen verwenden:
- AppEngineDataStoreFactory: die Anmeldedaten mithilfe der Google App Engine Data Store API beibehält
- MemoryDataStoreFactory: "bleibt dauerhaft" die Anmeldedaten im Arbeitsspeicher, was nur als kurzfristige Speicherung für die Lebensdauer des Prozesses sinnvoll ist.
- FileDataStoreFactory: und speichert die Anmeldedaten in einer Datei.
App Engine-Nutzer: AppEngineCredentialStore ist veraltet und wird bald entfernt. Wir empfehlen die Verwendung von AppEngineDataStoreFactory mit StoredCredential. Wenn Sie Anmeldedaten auf alte Weise gespeichert haben, können Sie die hinzugefügten Hilfsmethoden migrateTo(AppEngineDataStoreFactory) oder migrateTo(DataStore) um die Migration durchzuführen.
Sie können DataStoreCredentialRefreshListener und legen Sie ihn mithilfe von GoogleCredential.Builder.addRefreshListener(CredentialRefreshListener) als Berechtigungsnachweis fest.
Vorgang mit Autorisierungscode
Verwenden Sie den Vorgang mit Autorisierungscode, damit der Endnutzer Ihre Anwendung erteilen kann Zugriff auf ihre geschützten Daten in Google APIs zu erhalten. Das Protokoll für diesen Ablauf ist angegeben in Autorisierungscode gewähren
Dieser Ablauf wird mithilfe von GoogleAuthorizationCodeFlow implementiert. Folgende Schritte sind auszuführen:
- Der Endnutzer meldet sich bei Ihrer Anwendung an. Sie müssen diesen Nutzer durch eine Nutzer-ID, die für Ihre Anwendung eindeutig ist.
- AuthorizationCodeFlow.loadCredential(String) aufrufen) basierend auf der Nutzer-ID, um zu prüfen, ob die Anmeldedaten des Endnutzers bereits bekannt sind. Wenn ja, sind wir fertig.
- Falls nicht, rufen Sie AuthorizationCodeFlow.newAuthorizationUrl() auf. und den Browser des Endnutzers auf eine Autorisierungsseite weiterleiten, auf der Sie Anwendungen auf ihre geschützten Daten zugreifen können.
- Der Google-Autorisierungsserver leitet den Browser dann zurück zum
Weiterleitungs-URL, die von Ihrer Anwendung angegeben wird, zusammen mit einer
code
-Abfrage . Verwenden Sie den Parametercode
, um ein Zugriffstoken mithilfe von AuthorizationCodeFlow.newTokenRequest(String). - Verwenden Sie AuthorizationCodeFlow.createAndStoreCredential(TokenResponse, String)) Anmeldedaten für den Zugriff auf geschützte Ressourcen zu speichern und abzurufen.
Wenn Sie GoogleAuthorizationCodeFlow nicht verwenden, können Sie alternativ auch die niedrigeren Klassen nutzen:
- Verwenden Sie DataStore.get(String), um die Anmeldedaten basierend auf der Nutzer-ID aus dem Speicher zu laden.
- Verwenden Sie GoogleAuthorizationCodeRequestUrl, um den Browser auf die Autorisierungsseite weiterzuleiten.
- Verwenden Sie AuthorizationCodeResponseUrl, um die Autorisierungsantwort zu verarbeiten und den Autorisierungscode zu parsen.
- Verwenden Sie GoogleAuthorizationCodeTokenRequest, um ein Zugriffstoken und möglicherweise ein Aktualisierungstoken anzufordern.
- Erstellen Sie ein neues GoogleCredential und speichern Sie es mithilfe von DataStore.set(String, V).
- Greifen Sie mit der
GoogleCredential
auf geschützte Ressourcen zu. Abgelaufene Zugriffstokens werden automatisch mit dem Aktualisierungstoken (falls zutreffend) aktualisiert. Verwenden Sie den DataStoreCredentialRefreshListener und legen Sie ihn mithilfe von GoogleCredential.Builder.addRefreshListener(CredentialRefreshListener) für die Anmeldedaten fest.
Wenn Sie Ihr Projekt in der Google API Console einrichten, Sie können je nach verwendetem Ablauf verschiedene Anmeldedaten auswählen. Weitere Informationen finden Sie unter OAuth 2.0 einrichten. und OAuth 2.0-Szenarien. Code-Snippets für jeden der Abläufe finden Sie unten.
Webserveranwendungen
Das Protokoll für diesen Ablauf wird unter OAuth 2.0 für Webserveranwendungen verwenden.
Diese Bibliothek bietet Servlet-Hilfsklassen zur erheblichen Vereinfachung der Autorisierungscode-Vorgang für grundlegende Anwendungsfälle. Sie stellen einfach konkrete Unterklassen bereit, von AbstractAuthorizationCodeServlet und AbstractAuthorizationCodeCallbackServlet (von google-oauth-client-servlet) und fügen sie der Datei „web.xml“ hinzu. Sie müssen sich trotzdem noch um die melden Sie sich für Ihre Webanwendung an und extrahieren Sie eine Nutzer-ID.
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 } }
Google App Engine-Anwendungen
Der Autorisierungscode-Vorgang in App Engine ist fast identisch mit dem Servlet. mit dem Autorisierungscode, außer dass wir die Users Java API Der Nutzer Sie müssen angemeldet sein, damit das Java-API für Nutzer aktiviert werden kann. finden Sie Informationen zu Weiterleitung von Nutzern zu einer Anmeldeseite, wenn diese nicht bereits angemeldet sind, siehe Sicherheit und Authentifizierung (in web.xml).
Der Hauptunterschied zum Servlet-Fall besteht darin, dass Sie konkrete
abgeleiteten Klassen von
AbstractAppEngineAuthorizationCodeServlet und AbstractAppEngineAuthorizationCodeCallbackServlet
(von google-oauth-client-appengine.
Sie erweitern die abstrakten Servlet-Klassen und implementieren die Methode getUserId
.
mit dem Java-API für Nutzer. AppEngineDataStoreFactory
(von google-http-client-appengine)
ist eine gute Option, um den Berechtigungsnachweis mithilfe der Google App Engine-Daten
Store API
Leicht modifiziertes Beispiel aus 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(); } }
Ein weiteres Beispiel finden Sie unter storage-serviceaccount-appengine-sample.
Dienstkonten
GoogleCredential unterstützt auch Dienstkonten. Im Gegensatz zu den Anmeldedaten, mit denen eine Client-Anwendung Zugriff auf einen Endnutzerdaten haben, ermöglichen Dienstkonten Zugriff auf die Ihre eigenen Daten. Ihre Clientanwendung signiert die Anfrage nach einem Zugriffstoken mithilfe von Einen privaten Schlüssel, der von der Google API Console heruntergeladen wurde
Beispielcode aus 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(); ...
Ein weiteres Beispiel finden Sie unter storage-serviceaccount-cmdline-sample.
Identitätsdiebstahl
Sie können den Dienstkontoablauf auch verwenden, um die Identität eines Nutzers in einer Domain zu übernehmen, die die Ihnen gehören. Dieser Ablauf ähnelt dem oben beschriebenen Dienstkontovorgang, Sie können jedoch Rufen Sie zusätzlich GoogleCredential.Builder.setServiceAccountUser(String) auf.
Installierte Apps
Dies ist der unter OAuth 2.0 für installierte Anwendungen beschriebene Ablauf mit Autorisierungscode.
Beispiel-Snippet aus 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"); }
Clientseitige Anwendungen
So verwenden Sie den unter folgendem Link beschriebenen browserbasierten Clientfluss: OAuth 2.0 für clientseitige Anwendungen verwenden, gehen Sie in der Regel so vor:
- Endnutzer über den Browser auf die Autorisierungsseite weiterleiten GoogleBrowserClientRequestUrl um Ihrer Browseranwendung Zugriff auf die geschützten Daten des Endnutzers zu gewähren.
- Verwenden Sie die Google API-Clientbibliothek für JavaScript. um das Zugriffstoken zu verarbeiten, das im URL-Fragment unter der Weiterleitungs-URI gefunden wurde registriert in der Google API Console.
Verwendungsbeispiel für eine Webanwendung:
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
Bibliothek für Android:
Wenn Sie für Android entwickeln und die gewünschte Google API enthalten ist in der Bibliothek der Google Play-Dienste, verwenden Sie diese Bibliothek, um eine optimale Leistung zu erzielen. Wenn die Google API, die Sie mit Android verwenden möchten, nicht Teil der Bibliothek der Google Play-Dienste ist, können die Google API-Clientbibliothek für Java verwenden, die Android 4.0 (Ice Cream Sandwich) unterstützt (oder höher) und der hier beschrieben wird. Die Unterstützung für Android in der Google Die API-Clientbibliothek für Java ist @Beta.
Hintergrund:
Ab Eclair (SDK 2.1) werden Nutzerkonten auf einem Android-Gerät verwaltet über den Account Manager. Die gesamte Android-Anwendungsautorisierung erfolgt zentral vom SDK verwaltet und verwendet, AccountManager Sie geben den OAuth 2.0-Bereich an, den Ihre Anwendung benötigt, und Sie erhalten einen Zugriff Token, das verwendet werden soll.
Der OAuth 2.0-Bereich wird über den Parameter authTokenType
als oauth2:
angegeben.
und den Umfang. Beispiel:
oauth2:https://www.googleapis.com/auth/tasks
Legt den Lese-/Schreibzugriff auf die Google Tasks API fest. Wenn Sie mehrere OAuth 2.0-Bereiche, verwenden Sie eine durch Leerzeichen getrennte Liste.
Einige APIs haben spezielle authTokenType
-Parameter, die ebenfalls funktionieren. Beispiel:
„Aufgaben verwalten“ ist ein Alias für das oben gezeigte authtokenType
-Beispiel.
Sie müssen auch den API-Schlüssel aus der Google API Console: Andernfalls stellt das Token, das Sie vom AccountManager erhalten, nur anonymes Kontingent, das normalerweise sehr niedrig ist. Wenn Sie dagegen eine API erhalten Sie ein höheres kostenloses Kontingent und können optional die Abrechnung für die Nutzung einrichten. darüber stehen.
Beispiel-Code-Snippet aus 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; } }