この記事の内容は、2016年10月20日にサポート切れになります。

Google Developers Japanの記事: さよなら OAuth 1.0 (2LO)

OAuth 2.0に対応した記事は「Google Calendar API Client Javaを使ったアプリでサービスアカウントで認証するには」を参照ください。


Calendar API V2が11月17日に利用できなくなるため、まだバージョン2を利用しているアプリケーションは期限までにバージョン3のAPIに移行する必要があります。
Upgrade now to Calendar APIv3

Javaのクライアントライブラリを使ってGoogle Calendar APIに2-Legged OAuth(2LO)認証しアクセスするアプリケーションをCalendar API v3に移行するにあたって調べてみたところ、Calendar API Client Library for Javaを利用した2-Legged OAuthのサンプルがなかなか見つかりませんでした。

以下の、公式ブログの記事も情報が古くなっていて、現時点(2014/9/25)でダウンロード可能な最新のライブラリには適用できません。
Calendar API v3, 2-legged OAuth & Java

さらに探してみたところ、StackOverflowの「Google Calendar API returning “Invalid Credentials” (401)」に解決策がありました。

この情報を元に、ライブラリに含まれるコマンドラインアプリケーションのサンプルを2-Legged-OAuth対応にする手順を説明します。
https://code.google.com/p/google-api-java-client/source/browse?repo=samples#hg/calendar-cmdline-sample

また、API V3ではGoogle Developers ConsoleでAPIアクセスを許可する必要があるため、Google Apps 管理コンソールでのOAuth設定からGoogle Developers ConsoleでのCalendar APIのアクセス許可およびAPIキー取得までの手順を一通り説明し、その後サンプルコードの修正箇所について説明します。

Google Apps管理画面でOAuthキー情報を取得

管理画面にアクエスして[セキュリティ]を開きます。
GoogleApps_2LO_Settings_1
[詳細設定] > [OAuth ドメインキーを管理する]を選択します。
GoogleApps_2LO_Settings_2
[OAuthコンシューマーキー]、[OAuthコンシューマーシークレット]をこの画面で確認できます。
また、2-Legged OAuthを利用するので[2-Legged OAuthアクセス コントロール]の[すべてのAPIヘのアクセスを許可する]を有効にしておきます。
GoogleApps_2LO_Settings_3

Google Developers Consoleでプロジェクトを設定する

Google API V3からはGoogle Appsの特定ドメインへのみアクセスするアプリケーションであってもGoogle Developers Congoleでプロジェクトを作成し、プロジェクトごとにAPIアクセスを設定する必要があります。

Google Apps特権管理者アカウントで、Google Developers Consoleにアクセスします。
https://console.developers.google.com/

アクセスすると「My Project」1つプロジェクトが自動で追加されています。
GoogleDevelopersConsole_1
今回はそのままこのプロジェクトを使いますが、通常はアプリケーション毎にプロジェクトを作成します。

Calendar APIを有効にする

「My Project」を選択すると、Project Dashboardが開きます。
GoogleDevelopersConsole_2

左のメニューの[API]リンクまたはDashboard内の[Enable an API]ボタンをクリックします。
GoogleDevelopersConsole_3
[Enabled APIs]には、現在有効になっているAPIがリストされます。Big Query APIなどデフォルトで有効になっているAPIがいくつかあります。
[Browse APIs]より「Calendar API」を探し[OFF]ボタンをクリックして有効にします。
[Enabled APIs]のリストに「Calendar API」が移動していることを確認できます。
GoogleDevelopersConsole_4

APIキーを取得

次にプログラムで使用するプロジェクトのAPIキーを取得します。
メニューより[Credentials]を選択して、[API KEY]に表示される文字列がプログラムで使用するAPIキーになります。
GoogleDevelopersConsole_Credentials

Java Clientによる実装

Calendar APIアクセスの準備ができたので、サンプルプログラムを修正、実行して動作を確認していきます。

実行に必要なjarファイル

サンプルを実行するにあたってクラスパスには以下のjarファイルを追加する必要があります。

Google API関連

  • google-api-client-1.19.0.jar: Google API Client for Javaのベースとなるライブラリ
  • google-api-services-calendar-v3-rev92-1.19.0.jar: Calendar API Client Library for Java
  • google-oauth-client-1.19.0.jar: 2-Legged-OAuthのHMAC-SHA1署名の生成に利用
  • google-http-client-1.19.0.jar: Google API ClientのHTTPユーティリティ
  • google-http-client-jackson2-1.19.0.jar: APIから取得するJSONを処理

依存するライブラリ

普通にOAuth2認証を利用する場合は、jettyのOAuthライブラリなどを読み込む必要がありますが、2-Legged-OAuthで認証する場合は実行に必要となるライブラリはかなり省略できます。

サンプルプログラムの2-Legged OAuth対応

Calendar API Client for Javaに含まれるサンプルコードCalendarSample.javaを2-Legged OAuth認証に対応して実行してみます。

以下は、Calendar APIアクセスのサービスクラスcom.google.api.services.calendar.Calendarを2-Legged OAuthの各種パラメータをセットして初期化する処理を追加したCalendarSampleのmainメソッドです。

	public static void main(String[] args) {
        
		try {
			// initialize the transport
			httpTransport = GoogleNetHttpTransport.newTrustedTransport();

			// initialize the data store factory
			dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);

			OAuthParameters oauthParameters = new OAuthParameters();
			oauthParameters.consumerKey = "co-meeting.net";
			OAuthHmacSigner signer = new OAuthHmacSigner();
			signer.clientSharedSecret = "xxxxxxxxxxxxxxxxx";
			oauthParameters.signer = signer;

			CalendarRequestInitializer initializer = new CalendarRequestInitializer() {
				@Override
				protected void initializeCalendarRequest(
						CalendarRequest<?> calendarRequest) throws IOException {
					ArrayMap<String, Object> customKeys = new ArrayMap<String, Object>();
					customKeys.add("xoauth_requestor_id",
							"hrendoh@example.com");
					calendarRequest.setUnknownKeys(customKeys);
					calendarRequest.setKey("XXXXXXXXXXXXXXXXXXXXXXXX");
				}
			};

			// set up global Calendar instance
			client = new com.google.api.services.calendar.Calendar.Builder(
					httpTransport, JSON_FACTORY, oauthParameters)
					.setApplicationName(APPLICATION_NAME)
					.setCalendarRequestInitializer(initializer).build();

			// run commands
			showCalendars();
			addCalendarsUsingBatch();
			Calendar calendar = addCalendar();
			updateCalendar(calendar);
			addEvent(calendar);
			showEvents(calendar);
			deleteCalendarsUsingBatch();
			deleteCalendar(calendar);

		} catch (IOException e) {
			System.err.println(e.getMessage());
		} catch (Throwable t) {
			t.printStackTrace();
		}
		System.exit(1);
	}

2-Legged OAuthに関連するポイントを説明します。

Calendar APIへのアクセスを提供するCalendarクラスはCalendar.Builderで初期化します。
OAuth コンシューマーキーとコンシューマーシックレットは、Calendar.Builderのコンストラクタの第3引数に渡すOAuathParametersにセットします。

	OAuthParameters oauthParameters = new OAuthParameters();
	oauthParameters.consumerKey = "co-meeting.net";
	OAuthHmacSigner signer = new OAuthHmacSigner();
	signer.clientSharedSecret = "xxxxxxxxxxxxxxxxx";
	oauthParameters.signer = signer;

2-Legged OAuthでは、xoauth_requestor_idパラメータにアクセスする主体となるユーザーを渡します。
また、V3のAPIではGoogle Developers Consoleで作成したプロジェクトのAPIキーもリクエストで渡す必要があります。
これらのパラメータは、CalendarRequestInitializerで定義し、Calendar.BuilderのインスタンスメソッドsetCalendarRequestInitializerでセットします。

	CalendarRequestInitializer initializer = new CalendarRequestInitializer() {
		@Override
		protected void initializeCalendarRequest(
				CalendarRequest<?> calendarRequest) throws IOException {
			ArrayMap<String, Object> customKeys = new ArrayMap<String, Object>();
			customKeys.add("xoauth_requestor_id",
					"hrendoh@example.com");
			calendarRequest.setUnknownKeys(customKeys);
			calendarRequest.setKey("XXXXXXXXXXXXXXXXXXXXXXXX");
		}
	};

以上を対応して、CalendarSampleを実行するとカレンダーとイベントのCRUD処理を確認することができます。