OAuth 2.0'ı Java için Google API İstemci Kitaplığı ile Kullanma

Genel Bakış

Amaç: Bu belgede, GoogleCredential yardımcı program sınıfı için Google hizmetleriyle OAuth 2.0 yetkilendirmesi gerçekleştirin. Örneğin, sağladığımız genel OAuth 2.0 işlevleri hakkında bilgi edinmek için OAuth 2.0 ve Java için Google OAuth İstemci Kitaplığı.

Özet: Google hizmetlerinde depolanan korunan verilere erişmek için Yetkilendirme için OAuth 2.0. Google API'leri farklı istemci uygulaması türleri için OAuth 2.0 akışlarını destekler. Tüm bu akışlarda istemci uygulaması şuna benzer bir erişim jetonu ister: yalnızca istemci uygulamanızla ve korunan verilerin sahibiyle ilişkili emin olun. Erişim jetonu ayrıca sınırlı bir kapsamla ilişkilendirilir. istemci uygulamanızın erişebildiği veri türünü tanımlar (örneğin "Görevlerinizi yönetin"). OAuth 2.0 için önemli bir hedef, koruma altındaki verilere kolay erişim ve olası etkiyi en aza indirir. ihlal anlamına gelir.

Java için Google API İstemci Kitaplığı'ndaki OAuth 2.0 paketleri, genel amaçlı Java için Google OAuth 2.0 istemci kitaplığı.

Ayrıntılı bilgi için aşağıdaki paketlere ilişkin Javadoc dokümanlarına bakın:

Google API Konsolu

Google API'lerine erişebilmeniz için şurada bir proje oluşturmanız gerekir: Kimlik doğrulama ve faturalandırma için Google API Konsolu ister yüklü bir uygulama, ister mobil bir uygulama, bir web sunucusu veya tarayıcıda çalışan bir istemci olabilir.

Kimlik bilgilerinizi düzgün şekilde ayarlamayla ilgili talimatlar için API Konsolu Yardımı.

Kimlik bilgisi

GoogleCredential

GoogleCredential korumalı kaynaklara erişim için OAuth 2.0 için iş parçacığı açısından güvenli bir yardımcı sınıftır erişim jetonundan yararlanabilirsiniz. Örneğin, zaten bir erişim jetonunuz varsa şu şekilde istekte bulunabilir:

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 kimliği

Bu alternatif yeterlilik belgesi, Google App Engine App Identity Java API. İstemci uygulamasının bir App Identity API, son kullanıcı tarafından kullanılan istemciye uygulamanızın kendi verilerini oluşturun.

AppIdentityCredential'ı kullanın. (google-api-client-appengine'den). Google App Engine tüm bu işlemleri gerçekleştirdiğinden, bu kimlik bilgisi çok daha basittir gösterir. Yalnızca ihtiyacınız olan OAuth 2.0 kapsamını belirtin.

urlshortener-robots-appengine-sample parametresinden alınan örnek kod:

static Urlshortener newUrlshortener() {
  AppIdentityCredential credential =
      new AppIdentityCredential(
          Collections.singletonList(UrlshortenerScopes.URLSHORTENER));
  return new Urlshortener.Builder(new UrlFetchTransport(),
                                  GsonFactory.getDefaultInstance(),
                                  credential)
      .build();
}

Veri deposu

Erişim jetonunun geçerlilik bitiş tarihi genellikle 1 saattir ve bu tarihten sonra kullanmaya çalışırsanız hata alırsınız. GoogleCredential otomatik olarak "yenileme" işlemini Bu da yeni web sitesi oluşturmak için yeni bir erişim jetonu ekleyebilirsiniz. Bu, uzun ömürlü bir yenileme jetonuyla yapılır ve Yetkilendirme kodu akışı sırasında access_type=offline parametresi ( GoogleAuthorizationCodeFlow.Builder.setAccessType(String).

Çoğu uygulamanın, kimlik bilgisinin erişim jetonunu ve/veya yenileme jetonuna dokunun. Kimlik bilgilerinin erişimini ve/veya yenileme jetonlarını sürdürmek için Kendi DataStoreFactory uygulamanızı sağlayabilirsiniz StoredCredential ile veya kitaplık tarafından sağlanan aşağıdaki uygulamalardan birini kullanabilirsiniz:

AppEngine Kullanıcıları: AppEngineCredentialStore desteği sonlandırıldı ve yakında kaldırılacak. Optimum kampanya performansı için AppEngineDataStoreFactory StoredCredential ile kullanın. Eski yöntemlerle depolanmış kimlik bilgileriniz varsa eklenen yardımcı yöntemler migrateTo(AppEngineDataStoreFactory) veya migrateTo(DataStore) gerçekleştirebilirler.

Şunları kullanabilirsiniz: DataStoreCredentialRefreshListener ve GoogleCredential.Builder.addRefreshListener(CredentialRefreshListener) kullanarak kimlik bilgisi için ayarlayın.

Yetkilendirme kodu akışı

Son kullanıcının uygulamanıza izin vermesi için yetkilendirme kodu akışını kullanın Google API'lerinde korunan verilerine erişmelerine yardımcı olun. Bu akışa ilişkin protokol belirtilen Yetkilendirme Kodu Verme.

Bu akış, GoogleAuthorizationCodeFlow kullanılarak uygulanır. Adımlar aşağıdaki gibidr:

GoogleAuthorizationCodeFlow kullanmıyorsanız daha alt düzey sınıfları da kullanabilirsiniz:

Projenizi Google API Konsolu'nda oluşturduğunuzda, kullandığınız akışa bağlı olarak farklı kimlik bilgileri arasından seçim yapabilirsiniz. Daha fazla bilgi için OAuth 2.0'ı kurma başlıklı makaleye göz atın. ve OAuth 2.0 Senaryoları hakkında daha fazla bilgi edinin. Her bir akışa ait kod snippet'leri aşağıda verilmiştir.

Web sunucusu uygulamaları

Bu akışa ilişkin protokol şurada açıklanmıştır: Web Sunucusu Uygulamaları için OAuth 2.0'ı Kullanma.

Bu kitaplık, performansı önemli ölçüde basitleştirmek için servlet yardımcı sınıfları yetkilendirme kodu akışını izleyin. Yalnızca somut alt sınıflar sağlarsınız AbstractAuthorizationCodeServlet listesi ve AbstractAuthorizationCodeCallbackServlet (google-oauth-client-servlet'ten) ve web.xml dosyanıza ekleyin. Kullanıcıyla yine de ilgilenmeniz gerektiğini unutmayın. web uygulamanız için giriş yapın ve bir kullanıcı kimliği çıkarın.

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 uygulamaları

App Engine'deki yetkilendirme kodu akışı servlet ile neredeyse aynıdır yetkilendirme kodu akışını, yalnızca Google App Engine'in Kullanıcılar Java API'si. Kullanıcı Users Java API'nin etkinleştirilmesi için giriş yapılması gerekir; şunun hakkında bilgi için: kullanıcıları bir giriş sayfasına yönlendirirse, bu bilgilere göz atın. Güvenlik ve Kimlik Doğrulama (web.xml dosyasında).

servlet durumundan ilk fark, somut bir ortam sağlayarak alt sınıfları AbstractAppEngineAuthorizationCodeServlet ve AbstractAppEngineAuthorizationCodeCallbackServlet (google-oauth-client-appengine'den. Soyut servlet sınıflarını genişletir ve getUserId yöntemini uygularlar sizin için en uygun platformdur. AppEngineDataStoreFactory (google-http-client-appengine'den) Google App Engine Verilerini kullanarak kimlik bilgisini kalıcı hale getirmek için iyi bir seçenektir Store API'si.

calendar-appengine-sample'dan alınmış (biraz değiştirilmiş):

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();
  }
}

Daha fazla örnek için bkz. storage-serviceaccount-appengine-sample.

Hizmet hesapları

GoogleCredential hizmet hesaplarını da destekler. İstemci uygulamasının bir yardımcı olmak için, Hizmet Hesapları istemci uygulamasının sahip olmanız gerekir. İstemci uygulamanız, erişim jetonu isteğini Google API Konsolu'ndan indirilen bir özel anahtar.

plus-serviceaccount-cmdline-sample'dan alınan örnek kod:

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();
...

Daha fazla örnek için bkz. storage-serviceaccount-cmdline-sample.

Kimliğe Bürünme

Aynı zamanda hizmet hesabı akışını, aynı alan adındaki bir kullanıcının kimliğine bürünmek için de kullanabilirsiniz. sahip olmanız gerekir. Bu, yukarıdaki hizmet hesabı akışına çok benzer ancak ek olarak GoogleCredential.Builder.setServiceAccountUser(String) yöntemini çağırın.

Yüklü uygulamalar

Bu, Yüklü Uygulamalar için OAuth 2.0'ı Kullanma başlıklı makalede açıklanan komut satırı yetkilendirme kodu akışıdır.

Şu kaynaktan örnek snippet: 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");
}

İstemci tarafı uygulamalar

Şu makalede açıklanan tarayıcı tabanlı istemci akışını kullanmak için: İstemci Tarafı Uygulamaları için OAuth 2.0'ı Kullanma, şu adımları uygulamanız gerekir:

  1. Tarayıcıdaki son kullanıcıyı GoogleBrowserClientRequestUrl ve tarayıcı uygulamanızın son kullanıcının korunan verilerine erişmesine izin verin.
  2. JavaScript için Google API İstemci Kitaplığı'nı kullanın. yönlendirme URI'sindeki URL parçasında bulunan erişim jetonunu işlemek Google API Konsolu'nda kayıtlı olmalıdır.

Bir web uygulaması için örnek kullanım:

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

@Beta

Android ile kullanılacak kitaplık:

Android için geliştirme yapıyorsanız ve kullanmak istediğiniz Google API'si Google Play Hizmetleri kitaplığı en iyi performans ve deneyim için bu kitaplığı kullanın. Google API'si Google Play Hizmetleri kitaplığının bir parçası olmadığından, Android 4.0 (Ice Cream Sandwich) sürümünü destekleyen Java için Google API İstemci Kitaplığı'nı kullanabilir (veya daha yüksek) ya da burada açıklanmaktadır. Google'da Android desteği Java için API İstemci Kitaplığı @Beta'dır.

Arka plan bilgileri:

Eclair (SDK 2.1) ile başlayarak kullanıcı hesapları Android cihazda yönetilir hesap yöneticisini kullanarak. Tüm Android uygulaması yetkilendirmeleri merkezi olarak tarafından yönetilen bir uygulamadır. AccountManager (Hesap Yöneticisi). Uygulamanızın ihtiyaç duyduğu OAuth 2.0 kapsamını belirtirsiniz ve bir erişim döndürür jeton.

OAuth 2.0 kapsamı, authTokenType parametresi aracılığıyla oauth2: olarak belirtilir artı kapsam. Örneğin:

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

Bu, Google Görevler API'sine okuma/yazma erişimini belirtir. Birden fazla OAuth 2.0 kapsamları için boşlukla ayrılmış liste kullanın.

Bazı API'lerde de çalışan özel authTokenType parametreleri vardır. Örneğin, "Görevlerinizi yönetin" yukarıda gösterilen authtokenType örneğinin takma adıdır.

API anahtarını Google API Konsolu. Aksi takdirde, Hesap Yöneticisi'nin size verdiği jeton yalnızca olup olmadığını kontrol edin. Bu genellikle çok düşüktür. Bunun aksine, anahtarı ile daha yüksek bir ücretsiz kota alabilir ve isteğe bağlı olarak, kullanım için faturalandırmayı ayarlayabilirsiniz. bunun üstünde bir değer var.

Örnek kod snippet'i 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;
  }
}