JWT 内で AuthSub を使用する

このドキュメントでは、Flash または Silverlight アプリケーションから Google の AuthSub 認証システムを使用する方法について説明します。

: Google のウェブベース アプリケーション用のアカウント認証サービスである AuthSub には、概念がよく似ています。実装は異なりますが、その違いはクライアント アプリケーション デベロッパーにとって重要ではありません。一部のドキュメントでは、区別が無関係な文脈で gtag 用の AuthSub を「AuthSub」と呼んでいます。

gtagSub 用の AuthSub のインターフェースを使用すると、Flash や Silverlight アプリケーションを、保護された Google Data API フィードに対してユーザーに代わって認証できます。高いセキュリティを維持するため、このインターフェースにより、アプリケーションはユーザーのアカウントのログイン情報を処理することなく、認証トークンを取得できます。

JWT 用の AuthSub は JavaScript 用の AuthSub のバリアントです。JavaScript 用 AuthSub と同様に、Google 以外のドメインでホストされているウェブページからクライアント アプリケーションが認証できるように、クロスドメイン方式を提供します。認証サービスが標準のドメイン(www.google.com ではなく accounts.googleapis.com)にあり、外部サイトからドメインへのアクセスを可能にする crossdomain.xml ファイルを提供する点で異なります。

すべての Authentication サービス API の使用方法については、Google Accounts API グループもご覧ください。

対象者

このドキュメントは、Google サービスにアクセスする Flash または Silverlight ウェブ アプリケーションを開発しているプログラマーを対象としています。

このドキュメントは、Google Data API プロトコルAuthSub インターフェースの背後にある一般的な概念を理解していることを前提としています。また、読者は ViewModel でプログラミングする方法を理解していることを前提としています。

サポートされる環境

AuthSub for JWT は現在、Firefox 1.5 以降と Internet Explorer 6.0 以降(Flash 9.0 以降または Silverlight 2.0 以降)でサポートされています。

IMA 向け AuthSub の仕組み

ウェブ アプリケーション、Google 認証サービス、Google データサービス間の通信の仕組みについて、概要を示します。

  1. ユーザーに代わって Google データサービスにアクセスするには、ウェブ アプリケーションに有効な認証トークンが必要です。通常、アプリケーションはこのトークンを Cookie に保存します。このような Cookie が存在しない場合、ウェブ アプリケーションは、AuthSub を介してトークンを取得する必要があります。トークンを取得するために、ウェブ アプリケーションは Authentication サービスに対して AuthSub for JWT ログイン呼び出しを行い、アクセスするサービスを指定します。
  2. ウェブ アプリケーションからリクエストを受信すると、Authentication サービスはユーザーを [アクセス リクエスト] ページにリダイレクトします。このページでは、Google アカウントにログインし、Google サービスへのアクセスを許可または拒否するよう求められます。
  3. ユーザーは、ウェブ アプリケーションへのアクセスを許可するか拒否するかを決定します。ユーザーがアクセスを拒否した場合、ウェブ アプリケーションに戻るのではなく、Google ページにリダイレクトされます。
  4. ユーザーがログインに成功してアクセス権を付与すると、認証サービスは元の呼び出しを行ったウェブ アプリケーション URL にユーザーをリダイレクトします。リダイレクトは、クエリ パラメータを介して、指定されたサービスの認証トークンを配信します。アプリケーションは、トークンをユーザーのブラウザ(ウェブ アプリケーションのドメイン)に Cookie として保存する必要があります。トークンは取り消されるまで有効です。(トークンを取り消すタイミングに関するアドバイスについては、トークンについてのセクションをご覧ください)。
  5. ウェブ アプリケーションは、Google データサービスに接続し、サービスに送信される各リクエストとともに認証トークンを送信します。
  6. Google Data サービスがトークンを認識すると、リクエストされたデータが提供されます。

IMASub の AuthSub インターフェースを使用して

AuthSub for IMA(AuthSubAS)は、Google Data API を使用する Flash(または Silverlight)アプリケーション用のクロスドメイン AuthSub エンドポイントです。

AuthSubAS は、google.com にある AuthSub エンドポイントのミラーを提供し、追加の(crossdomain.xml)ファイルとともに Flash(または Silverlight)エンドポイントからアクセスできるようにします。たとえば、エンドポイント AuthSubSessionToken は、https://accounts.googleapis.com/accounts/AuthSubSessionToken にアクセスすることで使用できます。

以下で、認証トークンを取得し、それを使って Flash アプリケーションから Google サービスにアクセスする手順を説明します。

  1. クロスドメイン ポリシーを設定します。

    クロスドメインで Flash を使用するには、アクセスする外部ドメインごとに policy で初期化する必要があります。これを行うには、次のように、ドメインごとに DRM メソッド Security.loadPolicyFile(policy) を呼び出します。

    <?xml version="1.0" encoding="utf-8"?>
    <Application xmlns="http://www.adobe.com/2006/mxml"
      initialize="onInitialized()"
      applicationComplete="onLoaded()">
      <Script>
        import flash.external.ExternalInterface;
        import flash.net.navigateToURL;
        import mx.controls.Alert;
    
        private function onInitialized() : void {
          // Load the cross domain policy file for each of the googleapis.com
          // domains used. At the very least, we need the ones for the API (photos,
          // in this case) and the one for AuthSub for ActionScript (accounts).
          Security.loadPolicyFile('http://photos.googleapis.com/data/crossdomain.xml');
          Security.loadPolicyFile('https://accounts.googleapis.com/crossdomain.xml');
        }
    
    

    サンプル全体を見る

    ここでは、accounts.googleapis.com(AuthSubAS)と photos.googleapis.com/data(この例で後述する PicasaWeb)のポリシーを読み込んでいます。

  2. 1 回限りのトークンをリクエストします。

    AuthSub プロセスの最初のステップは AuthSub エンドポイントからの 1 回限りのトークンのリクエストです。アプリケーションでこれを行うには、次のように AuthSubRequest エンドポイントの呼び出しを行います。

          var getTokenPage : URLRequest = new URLRequest('https://www.google.com/accounts/AuthSubRequest');
    
          // Construct the parameters of the AuthSub request. These are the same parameters
          // as normal AuthSub, which can be found here: /accounts/docs/AuthSub.html#AuthSubRequest
          var authSubParams : URLVariables = new URLVariables();
          authSubParams['scope'] = 'http://photos.googleapis.com/data'; // photos API
          authSubParams['session'] = 1; // single-use token
          authSubParams['secure'] = 0; // non-secure apps
          authSubParams['next'] = 'photos.swf'; // The URL of this app.
    
          getTokenPage.data =  authSubParams;
          navigateToURL(getTokenPage, '_top');
    
    

    サンプル全体を見る

    このメソッドには scope の値が必要です。各 Google サービスは、許可するアクセスのスコープを定義するため、トークン リクエスト内でそのスコープを参照する必要があります。使用するスコープ値を確認するには、アクセスする Google サービスのドキュメントをご覧ください。スコープは URL のように見えますが、サービスを識別する単純な URL でも、読み取り専用によるアクセスの制限など、より制限されたアクセスを指定することもできます。サービスでスコープを選択できる場合は、最も厳密にスコープが設定されたトークンをリクエストします。たとえば、Google カレンダーのデータフィードにアクセスするには、'http://www.google.com/calendar' ではなく、スコープ 'http://www.google.com/calendar/feeds' を使用します。

    ヒント:

    • ユーザーに手動でログイン プロセスを開始するように促すログイン ボタンなどのユーザー入力メカニズムを提供することを強くおすすめします。代わりに、読み込みの直後にユーザーの操作やリダイレクトを待たずにチェックしてリダイレクトする場合、ユーザーが最初にページに到着したときに表示されるのは Google のログインページです。ユーザーがログインしなかった場合、Google はユーザーをページにリダイレクトしません。ユーザーの視点から見ると、ユーザーはページにアクセスしようとしましたが、送信されず、また送信されていません。ユーザーが混乱し、混乱する恐れがあります。
    • ユーザーが複数の Google サービスにアクセスする必要があるアプリケーションは、サービスごとに新しいトークンをリクエストする必要があります(サービスごとにスコープが異なるため)。

  3. 認証トークンをリクエストします。

    AuthSubRequest エンドポイントは、ユーザーのブラウザの URL を http://yourWebAppUrl?token=singleUseToken に設定して、1 回限りのトークンを返します。アプリケーションが 1 回限りのトークンを受け取ったら、そのトークンを複数回(長い)トークンと交換する必要があります。このトークンを使用して、Google データフィードに対してリクエストできます。そのためには、単一用途トークンを指定して AuthSubSessionToken メソッドを呼び出します。

    アプリケーションは、読み込まれたときに URL の token パラメータを確認する必要があります。

        private function onLoaded() : void {
    
          // Once the application has loaded, check to see if an AuthSub token was
    // placed into the current page's URL. If it was, the user has already
    // authenticated, and we can continue to connect to the the service itself. var searchPortion : String = ExternalInterface.call('window.location.search.toString'); if (searchPortion.length > 0) { // remove the ? from the token and extract the token. searchPortion = searchPortion.substring(1); // NOTE: Real applications should parse the URL properly. if (searchPortion.indexOf('token=') == 0) { getLongLivedToken(searchPortion.substring(6)); return; } // more code ... }

    サンプル全体を見る

    トークンが見つかった場合は、getLongLivedToken のようなメソッドを呼び出す必要があります。このメソッドは AuthSubSessionToken エンドポイントを呼び出します。

        private function getLongLivedToken(singleUseToken : String) : void {
          // Construct a call to the AuthSub for ActionScript endpoint on accounts.googleapis.com.
          // This call will exchange the single use token given to use by AuthSub for a long-term
          // token that we can use to make requests to endpoints such as Photos.
          var getTokenRequest : URLRequest = new URLRequest('https://accounts.googleapis.com/accounts/AuthSubSessionToken');
    
          // Due to a bug in Flash, a URLRequest with a GET request will
          // not properly send headers. We therefore use POST for this and *ALL*
          // requests.
          getTokenRequest.method = URLRequestMethod.POST;
    
          // Due to a bug in Flash, a URLRequest without a valid parameter will
          // not properly send headers. We therefore add a useless parameter to
          // make this code work.
          getTokenRequest.data = new URLVariables('pleaseignore=ignore');
    
          // Add the AuthSub for ActionScript headers.
          getTokenRequest.requestHeaders.push(new URLRequestHeader('Authorization', 'AuthSub token="' + singleUseToken + '"'));
    
          // Create the loader to get the token itself. The loader will callback
          // to the following event handlers if and when the server responds.
          var getToken : URLLoader = new URLLoader();
          getToken.addEventListener(Event.COMPLETE, onGetTokenResult);
          getToken.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onGetTokenFailed);
          getToken.addEventListener(IOErrorEvent.IO_ERROR, onGetTokenFailed);
    
          try {
            getToken.load(getTokenRequest);
          } catch (e : Error) {
            Alert.show('Some error occurred: ' + e);
          }
    
    

    サンプル全体を見る

    onGetTokenResult ハンドラのようなメソッドは、返されたトークンを保存します。

        private function onGetTokenResult(e : Event) : void {
          // Load the parameters from the response.
          var getToken : URLLoader = URLLoader(e.target);
          var params : URLVariables = new URLVariables(getToken.data);
    
          // Parse the session token from the result. Real applications
          // might at this point store the token in a long-term cookie so
          // that repeated usages of the application do not require this entire
          // authentication process.
          sessionToken = params.Token;
    
          // Trim the newline from the end of the session token.
          sessionToken = sessionToken.substring(0, sessionToken.length - 1);
       }
    
    

    サンプル全体を見る

    ヒント:

    • アプリケーションで長期トークンを Cookie に保存し、短期トークンのチェックの前に確認することを強くおすすめします。これにより、ユーザーがアプリケーションを使用するたびに AuthSub の確認ページにアクセスする必要がなくなります。

  4. 認証トークンを使用する。

    認証トークンを使用するには、Authorization ヘッダーを介して Google サービスに対するリクエストにトークンを関連付けます。

    Authorization: AuthSub token="(session token goes here)"

    フォトサービスの gtag の例:

          // Prepare a request to the photos API for the private album
          // of the user.
          var albumRequest : URLRequest = new URLRequest('http://photos.googleapis.com/data/feed/api/user/default');
          albumRequest.data = new URLVariables('access=private&v=2&err=xml');
    
          // Due to a bug in Flash, a URLRequest with a GET request will
          // not properly send headers. We therefore use POST for this and *ALL*
          // requests.
          albumRequest.method = URLRequestMethod.POST;
    
          var authsubHeader : String = 'AuthSub token="' + sessionToken + '"';
    
          // Add the Authorization header which uses the session token.
          albumRequest.requestHeaders.push(new URLRequestHeader('Authorization', authsubHeader));
    
          // The X-HTTP-Method-Override header tells the Photos API to treat this request
          // as a GET request, even though it is being conducted as a POST (due to the bug
          // mentioned above). This is very important, as GData APIs will react differently
          // to different HTTP request types.
          albumRequest.requestHeaders.push(new URLRequestHeader('X-HTTP-Method-Override', 'GET'));
    
          // We expect ATOM XML to be returned.
          albumRequest.requestHeaders.push(new URLRequestHeader('Content-Type', 'application/atom+xml'));
    
    

    サンプル全体を見る

  5. ログアウト ボタンやクリック可能なリンクなど、手動ログアウト機能を提供することをおすすめします。この方法の場合、ユーザーは好きなときにログアウトするか、ログインしたままにして次にアプリケーションにアクセスしたときもデータ フィードを手軽に利用できるようにすることができます。

トークンについて

ここでは、AuthSub が JWT に使用するトークンについて説明します。多くの場合、この情報を知る必要はありません。

各認証トークンは、以下のデータに固有のものです。

  • Google サービスのスコープ
  • ユーザーの Google アカウント
  • クライアント アプリケーション

トークンデータを使用すると、指定したサードパーティ アプリケーションのみがデータをリクエストでき、このリクエストは指定したスコープとユーザー アカウントのデータに限定されます。

スコープ、ユーザー、クライアントの組み合わせに対して一度に有効にできるトークンは 1 つのみです。ウェブ アプリケーションは、特定のユーザーの新しい Google サービスにアクセスする必要があるたびに新しいトークンをリクエストする必要があります。トークンの対象となるアクセスの範囲は Google サービスによって異なります。Google サービスでは、読み取り専用アクセスなど、特定のタイプのデータやアクティビティへのアクセスを制限する場合があります。

AuthSub for IMA インターフェースから返されたトークンは、取り消されるまで何度でも使用できます。トークンのライフサイクルを管理するのはアプリケーション次第です。セキュリティと利便性のバランスを取ることも重要です。新しいセッションが開始されるたびに新しいトークンをリクエストすることをおすすめします。

一部の Google サービスでは、安全なトークンを使用して登録され、ウェブ アプリケーションからのみアクセスを許可できます。そのようなサービスの AuthSub for JWT はサポートされていません。セキュア トークンを使用するには、組織が SSL 証明書を Google に登録し、それらのデータフィードに対するすべてのリクエストに署名する必要があります。

トップへ戻る