IBM Cloud Docs
アプリケーション識別および許可

アプリケーション識別および許可

IBM Cloud® App ID を導入すると、OAuth2.0 機能を利用したアプリケーション識別および許可フローを使用して、アプリケーションを保護することができます。

通信フローについて

さまざまな場面で、あるアプリケーションがユーザー介入なしで別のサービスまたはアプリと通信できると便利です。 例えば、非対話式アプリが作業を実行するために、別のアプリケーションへのアクセスが必要になる場合があります。 これが必要になる発信元としては、プロセス、CLI、デーモンなどが含まれます。また、モニターを行ってアップストリーム・サーバーに環境変数を報告する IoT デバイスも含まれます。 具体的なユース・ケースはアプリケーションごとに異なりますが、留意すべき最も重要な点は、要求がエンド・ユーザーではなくアプリのために交換されること、また認証と許可の対象がアプリであることです。

フローの仕組み

App ID は、OAuth 2.0 クライアント資格情報フローを利用して通信を保護します。 アプリが App ID に登録されると、そのアプリはクライアント ID とシークレットを取得します。 アプリは、これらの情報を使用して App ID にアクセス・トークンを要求し、保護リソースまたは保護 API へのアクセスが許可されます。 アプリケーション識別および許可フローでは、アプリケーションに与えられるのはアクセス・トークンのみです。 識別トークンやリフレッシュ・トークンは取得しません。 トークンについて詳しくは、トークンについてを参照してください。

このワークフローは、秘密が悪用されたり漏洩したりする危険性がない、信頼できるアプリケーションでのみ使用されることを意図している。 アプリケーションは常にクライアント・シークレットを保持します。 モバイル・アプリには向いていません。

フローの概要

以下のイメージは、サービスとアプリケーションの間の通信の方向を示しています。

caption-side=bottom"
App ID アプリケーション・アイデンティティと認可フロー アプリケーション・アイデンティティと認可フロー

  1. 保護リソースにアクセスするために認証を受ける必要があるアプリケーションを App ID に登録します。
  2. アプリケーション A は、App ID に登録され、クライアント ID とシークレットを取得します。
  3. アプリケーション A は、前のステップで取得した資格情報を送信して、App ID 許可サーバーの /tokenエンドポイントに要求を行います。
  4. App ID は要求を検証し、アプリを認証し、アクセス・トークンを入れた応答をアプリケーション A に返します。
  5. アプリケーション A は、その有効なアクセス・トークンを使用して、アプリケーション B などの保護リソースに要求を送信できるようになりました。

クライアントの認証に使用するクライアント・シークレットは、機密性が非常に高いので機密を維持する必要があります。 アプリケーションはアプリ内でクライアントシークレットを使用するため、このワークフローは信頼できるアプリケーションでのみ使用しなければならない。 信頼できるアプリケーションを使用することで、クライアント・シークレットの漏えいや悪用を防止します。

アプリの登録

GUI を使用する場合

  1. App ID ダッシュボードの**「アプリケーション」タブで、「アプリケーションの追加」**をクリックします。
  2. アプリケーション名を追加し、**「保存」**をクリックして、登録済みアプリのリストに戻ります。 アプリケーションの名前は 50 文字を超えてはなりません。
  3. 登録済みアプリのリストから、前のステップで追加したアプリケーションを選択します。 行が展開され、資格情報が表示されます。

API を使用する場合

  1. /management/v4/<tenantID>/applications エンドポイントに対して POST 要求を行います。

    curl -X POST \  https://<region>.appid.cloud.ibm.com/management/v4/<tenantID>/applications/ \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer <IAMToken>' \
    -d '{"name": "<applicationName>"}'
    

    応答の例:

    {
    "clientId": "c90830bf-11b0-4b44-bffe-9773f8703bad",
    "tenantId": "b42f7429-fc24-48fa-b4f9-616bcc31cfd5",
    "secret": "YWQyNjdkZjMtMGRhZC00ZWRkLThiOTQtN2E3ODEyZjhkOWQz",
    "name": "testing",
    "oAuthServerUrl": "https://us-south.appid.cloud.ibm.com/oauth/v4/b42f7429-fc24-48fa-b4f9-616bcb31cfd5",
    "profilesUrl": "https://us-south.appid.cloud.ibm.com",
    "discoveryEndpoint": "https://us-south.appid.cloud.ibm.com/oauth/v4/b42f7429-fc24-48fa-b4f9-616bcb31cfd5/.well-known/openid-configuration"
    }
    

アクセス・トークンの取得

アプリが App ID に登録され、資格情報を取得したら、App ID 許可サーバーに要求を行ってアクセス・トークンを取得することができます。

  1. /token エンドポイントに HTTP POST リクエストを行う。 要求の許可は Basic auth であり、クライアント ID とシークレットを Base64 でエンコードしたユーザー名およびパスワードとして使用します。

    curl -X POST https://<region>.appid.cloud.ibm.com/oauth/v4/<tenantID>/token \
       -H 'Authorization: Basic base64Encoded{clientId:secret}' \
       -H 'Content-Type: application/x-www-form-urlencoded' \
       -d 'grant_type=client_credentials'
    

    応答の例:

    {
    "access_token": "eyJhbGciOiJS...F9A",
    "expires_in": "3600",
    "token_type": "Bearer"
    }
    

チュートリアル: Node.js SDK を使用したエンドツーエンドのフロー

  1. 以下のいずれかの方法でアクセス・トークンを取得します。

    • App ID Node.js サーバー SDK から、トークン マネージャーを使用します。 アプリの資格情報を使用してトークン・マネージャーを初期化し、getApplicationIdentityToken() メソッドを呼び出してトークンを取得します。

      const TokenManager = require('ibmcloud-appid').TokenManager;
      const config = {
      clientId: "<clientID>",
      tenantId: "<tenantID>",
      secret: "{secret}",
      oauthServerUrl: "https://<region>.appid.cloud.ibm.com/oauth/v4/<tenantID>"
      };
      const tokenManager = new TokenManager(config);
      tokenManager.getApplicationIdentityToken().then((appIdAuthContext) => {
      console.log(' Access tokens from SDK : ' + JSON.stringify(appIdAuthContext));
      }).catch((err) => {
      //console.error('Error retrieving tokens : ' + err);
      });
      
    • App ID 許可サーバーから取得する。

      要求内の oauthServerUrl は、アプリケーションの登録時に取得します。 管理 API を使用してアプリを登録した場合、このサーバー URL は応答本文に含まれています。 IBM Cloud コンソールでアプリをバインドして登録した場合、URL は VCAP_SERVICES JSON オブジェクトまたは Kubernetes シークレットで見つけることができます。

      var request = require('request');
      function getAccessToken() {
      let options = {
            method: 'POST',
            url: oauthServerUrl + '/token',
            headers: { 'content-type': 'application/x-www-form-urlencoded',
               'Authorization': 'Basic ' +Buffer.from('clientId: secret').toString('base64')
            },
            form: {
               grant_type: 'client_credentials'
            }
      };
      return new Promise((resolve, reject) => {
            request(options, function (error, response, body) {
               if (error) {
                  return reject(error);
               }
               let data = JSON.parse(body);
               if(data.access_token) {
                  resolve(data.access_token);
               } else {
                  reject(data);
               }
            })
      });
      }
      
  2. 前のステップで取得したアクセス・トークンを使用して、保護リソースへの要求を行います。

    let options = {
       method: 'GET',
       url: 'http://localhost:8081/protected_resource',
       headers: { authorization : 'Bearer ' + accessToken}
    }
    request(options, function (error, response, body) {
       if (error) {
          console.log(error)
       } else {
             res.status(response.statusCode).send({
       console.log(JSON.stringify(body));
             });
       }
    });
    
  3. App ID Node.js SDK に用意されている API 戦略を使用して、保護リソースをセキュアにします。

    const express = require('express'),
       passport = require('passport');
       APIStrategy = require("ibmcloud-appid").APIStrategy;
    var app = express();
    app.use(passport.initialize());
    passport.use(new APIStrategy({
       oauthServerUrl: "https://{region}.appid.cloud.ibm.com/oauth/v4/{tenant-ID}",
       tenantId:"{tenant-ID}"
    }));
    app.get('/protected_resource',
       passport.authenticate(APIStrategy.STRATEGY_NAME, {session: false}),
       (req, res) => {
             res.send("Hello from protected resource");
    });