Help us understand the problem. What is going on with this article?

GoogleアカウントでAWSサービスに接続する

More than 1 year has passed since last update.

はじめに

こんにちは。Daddy's Officeの市川です。

私が10年以上開発を続けているWindowsPCを監視カメラシステムにする「LiveCapture3」。
先日、このWindowsアプリにクラウド経由で接続するスマホアプリ「LiveCapture3 Remote」をリリースしました。

クラウドサーバはAWSを使用してサーバレスで構築したので、アプリサインインは、Googleアカウントでサインインし、AWS Cognitoでユーザに対して適切なIAM権限を付与する形で実現しています。

Googleアカウント認証の有効化

Googleアカウント認証をアプリで使用するには、まず、Googleアカウント認証を有効にする必要があります。

まずFireBase Consoleにログインし、(プロジェクトを作成していなければ作成して)左サイドメニューから「Authentication」を選択します。

Authenticationページの「ログイン方法」タブをクリックすると、ログインプロバイダ一覧が表示されますので、一覧から「Google」を選択して、有効にします。

image.png

image.png

この段階では、アプリ情報の追加などはせずに、一旦保存します。

保存後、Google Developer Consoleにアクセスし、「認証情報」ページを開くと、OAuth2.0クライアントIDの一覧に、Web client用のIDが自動的に追加されているはずです。

image.png

このWeb client用のID「xxxxxxxxxxx.apps.googleusercontent.com」は、AWSのIDプロバイダ設定で使用しますので、コピーしておいてください。

IDプロバイダーの追加(AWS)

Googleアカウントで認証済みのアプリからのアクセスに対して、AWSサービスへアクセスするAWS認証情報を発行するために、CognitoのIDプールとGoogleアカウントを連携させます。

CognitoのIDプールには、Google+が選択肢として出てきますが、Google+はすぐに使えなくなりそうなので、別途、OpenIDのプロバイダを作成します。

IAMの「IDプロバイダー」を選択して、「プロバイダの作成」ボタンをクリックします。

image.png

項目 入力値
プロバイダーのタイプ OpenID Connect
プロバイダーのURL accounts.google.com
対象者 Google Developer Console上に表示されたWeb client用のID「xxxxxxxxxxx.apps.googleusercontent.com」

上記を入力して、IDプロバイダー(accounts.google.com)を作成します。

Cognito IDプールの作成(AWS)

OpenIDのIDプロバイダを追加すると、CognitoのIDプール作成画面のOpenIDのタブに、今追加した「accounts.google.com」が選択肢として表示されますので、チェックを入れます。

image.png

今回は認証されていないIDのアクセスは拒否しますので、そのままIDプールを作成します。

AWS認証情報の権限設定

CognitoでIDプールを作成すると、2つのIAMロールが生成されます。

  • Cognito_xxxxxxAuth_Role (認証済みユーザ用のIAMロール)
  • Cognito_xxxxxxUnauth_Role(認証されていないユーザ用のIAMロール)

(xxxxxxは作成したIDプールの名称です)

先ほどのIDプール作成で、「認証されていないIDに対してのアクセスを有効にする」にチェックを入れると、認証していないユーザにもAWSサービスへのアクセスを許可することができます。

ただ、今回は使用しませんので、認証済みユーザ向けの「Cognito_xxxxxxxAuth_Role」の方に、必要なアクセス権を設定します。

AndroidアプリをOAuth Clientとして追加

ここまでの設定で、Googleアカウント認証とAWSの連携はできました。
ただ、OAuthクライアントとして登録しているのはWeb clientだけです。

今回は、Androidアプリのサインイン処理で使用しますので、AndroidアプリをOAuthクライアントとして追加する必要があります。

1. フィンガープリントの取得

まず、利用するAndroidアプリのフィンガープリント(SHA-1)を取得します。
Debug版の場合は、ビルドしたマシン毎にローカルにデバッグ用のKeyStoreが作成されてアプリに署名されますので、そのKeyStoreを指定してKeyToolでフィンガープリントを表示させます。

(Release版は後程説明します)

Debug版KeyStoreの場所

OS 場所
Windows C:\Users<user>.android\debug.keystore
MacやLinux ~/.android/debug.keystore

フィンガープリントの取得

上記のKeyStoreを指定して、KeyToolを実行します。

keytool -v -list -keystore [keystore名]

表示されたSHA-1のフィンガープリントをコピーしておきます。

2. FireBaseプロジェクトにアプリを登録

FireBase Consoleを開き、「プロジェクトの設定」を選択します。

image.png

アプリをつ一つも追加していない場合は、下記のようにアプリ選択の画面が表示されます。

image.png

今回はAndroidアプリを追加しますので、アンドロイドアイコンをクリックして表示されるアプリ登録画面上で、パッケージ名と、取得したフィンガープリント(SHA-1)を入力し、アプリを登録します。

アプリ登録後、Google Developer Consoleにアクセスし、「認証情報」ページを開きます。

そうすると、OAuth2.0クライアントIDの一覧に、Web client用のIDだけでなく、Android用のアプリクライアントIDが自動生成されているはずです。(「タイプ」がAndroidのキー)

これをコピーしておきます。

3. IDプロバイダーの対象者にAndroid用クライアントIDを追加(AWS)

AWSのIAMページで、先ほど追加した、accounts.google.comを選択し、対象者にAndroid用のクライアントIDを追加します。

image.png

これで、AndroidアプリでGoogleアカウント認証を行い、AWSサービスにアクセスする準備ができました。

実装

Googleアカウントへのサインイン処理の実装方法については色々と情報がありますので、そちらを参照してください。
私は下記の記事を参考にさせていただきました。

Google Sign-In

Googleサインインが成功すると、GoogleSignInAccountが取得できます。
このアカウントオブジェクトのgetIdToken()メソッドで、OpenID Connectで使用するJWTトークンが取得できますので、それを使用して、AWSサービスにアクセスする際のCredentialオブジェクトを生成します。

        CognitoCachingCredentialsProvider credentialsProvider 
                = new CognitoCachingCredentialsProvider(
                                mContext,            // context
                                COGNITO_IDP_ID,      // Cognito IDプールのID
                                Regions.AP_NORTHEAST_1);

        // mAccountは、サインイン成功で返却されたGoogleSignInAccountオブジェクト
        Map<String, String> logins = new HashMap();
        logins.put("accounts.google.com", mAccount.getIdToken());

        credentialsProvider.setLogins(logins);

このCredentialをAWS SDKの各サービス用クライアント生成時に使用することで、AWSサービスに設定された権限でアクセスが可能になります。

注意事項

認証の有効期限

取得した認証トークンには有効期限があります。
Cognitoユーザプール経由で認証を行うと、トークンのリフレッシュはSDK内部で自動的に行ってくれるようなのですが、今回の方法では自分で実装する必要があります。

有効期限が切れると、AWS SDKから、下記のExceptionが発生します。

com.amazonaws.services.cognitoidentity.model.NotAuthorizedException

これをCatchしたら、再ログイン処理を行ってから再試行する、という実装が必要です。

Release版のフィンガープリント

Androidアプリ用のOAuthクライアントIDは、フィンガープリントが異なるRelease版は別途登録する必要があります。

登録方法はDebug版と同じなのですが、PlayStoreに「GooglePlayアプリ署名」を利用してアップロードしたアプリの場合、フィンガープリントはPlayStore側で付け替えられてしまいますので、Google Play Consoleからフィンガープリントを取得する必要があります。

GooglePlayアプリ署名とは

その場合、Google Play Consoleを開き、アプリの署名ページで表示されるSHA-1フィンガープリントを登録します。

image.png

参考

以下のページを参考にさせていただきました。
Google Sign-In
GooglePlayアプリ署名とは

Yukio-Ichikawa
Daddy's Office代表 Windowsアプリケーション、クラウドアプリケーション、スマホアプリケーション開発を行っています。
https://lc3.daddysoffice.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした