ハウツーガイド - AWSサービス認証

このページは機械翻訳により提供されています。翻訳内容と英語版に相違がある場合は、英語版が優先されます。

AWSサービスは2つの方法で認証できます。 Workatoは、AWS V4署名の生成を支援して認証プロセスを簡素化するAWSライブラリをサポートしているため、アクションとトリガーの構築に集中できます。

このガイドでは、次の両方に対してデュアル認証を実装する方法を説明します。

認証にはIAMロールを推奨

AWSとWorkatoはどちらも、AWS IAMロール認証の使用を推奨しています。 これをコネクタのユーザー向けのデフォルト認証方法にすることをお勧めします。

IAMロールの作成とARNの取得

Workato用のIAMロールを作成し、Amazonリソースネーム(ARN)を取得する方法については、AWS向けIAMロールベース認証ページを参照してください。

サンプルコネクター - 汎用コネクター

ruby
{
  title: "Sample AWS S3 Connector",

  connection: {
    fields: [
      {
        name: "aws_auth_type",
        label: "AWS Authorization type",
        control_type: "select",
        optional: false,
        pick_list: [
          ["IAM role", "aws_role_based"],
          ["Access key", "aws_key_secret"]
        ],
        default: "aws_role_based",
        hint: 'Learn more about Amazon S3 authorization support <a href="http://docs.workato.com/connectors/s3.html#connection-setup" target="_blank">here</a>.'
      },
      {
        name: "aws_assume_role",
        label: "IAM role ARN",
        optional: false,
        ngIf: 'input.aws_auth_type == "aws_role_based"',
        help: {
          title: "Using IAM Role authorization",
          text: <<~HELP
            Create an IAM role in your AWS account using the following data:
            <br/>&nbsp;- Use Workato AWS Account ID <b>{{ authUser.aws_iam_external_id }}</b>
            to generate the <b>Principal</b> for the role.
            <br/>&nbsp;- Use <b>{{ authUser.aws_workato_account_id }}</b> as the <b>External ID</b> for the role.
            <br/>&nbsp;- Set this field's value to the newly created role's ARN.
            <br/><a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html"
            target="_blank">Learn more</a>.
          HELP
        }
      },
      {
        name: "aws_api_key",
        label: "Access key ID",
        control_type: "password",
        optional: false,
        hint: "Go to <b>AWS account name</b> > <b>Security Credentials</b> > <b>Users</b>. Get API key from existing user or create new user.",
        ngIf: 'input.aws_auth_type == "aws_key_secret"'
      },
      {
        name: "aws_secret_key",
        label: "Secret access key",
        control_type: "password",
        optional: false,
        hint: "Go to <b>AWS account name</b> > <b>Security Credentials</b> > <b>Users</b>. Get secret key from existing user or create new user.",
        ngIf: 'input.aws_auth_type == "aws_key_secret"'
      },
      {
        name: "aws_region",
        optional: false,
        hint: "AWS service region. If your account URL is <b>https://eu-west-1.console.s3.amazon.com</b>, use <b>eu-west-1</b> as the region."
      }
    ],

    authorization: {
      type: "custom_auth"
    }
  },

  test: lambda do |connection|
    call(:list_buckets, connection)
  end,

   methods: {
    list_buckets: lambda do |connection|
      signature = aws.generate_signature(
        # The connection object defined earlier.
        connection: connection,
        # The internal name of the AWS service you are targeting
        service: "s3",
        # The AWS service region you are targeting.
        # For services with a globally unique endpoint such as IAM, use us-east-1.
        region: connection["aws_region"],
        # The host of the API url.
        # Optional and defaults to "#{service}.#{region}.amazonaws.com".
        # In some cases like AWS API Gateway and AWS IAM, your host may not follow this standard and require you to override the host.
        host: "s3.dualstack.#{connection['aws_region']}.amazonaws.com",
        # The relative path of the endpoint. Optional and defaults to "/"
        path: "/",
        # The verb used for the request. Optional and defaults to "GET"
        method: "GET",
        # The query parameters for the request. Optional and defaults to {}
        params: { "list-type" => 2, "max-keys" => 1000 },
        # The headers for the request. Optional and defaults to {}
        headers: {},
        # The payload for the request. Optional and defaults to ""
        payload: ""
      )
      url = signature[:url]
      headers = signature[:headers]

      response = get(url).headers(headers).response_format_xml

      files = response.dig("ListBucketResult", 0, "Contents")
      files = Array.wrap(files).map do |content|
        content.each_with_object({}) do |(k, v), obj|
          obj[k] = Array.wrap(v).dig(0, "content!")
        end
      end

      { "files" => files }
    end
  }
}

ステップ1 - コネクションフィールドの定義

connectionキーでは、ハッシュの配列としてfieldsキーに入力フィールドを定義します。 配列内の各ハッシュは、単一の入力フィールドを表します。 その中で、入力フィールドの名前やエンドユーザーに表示されるヒントなどのパラメーターを宣言できます。 この例では、ユーザーが認証するための2つの方法を提示しており、どちらを使用するかはaws_auth_typeフィールドへの入力によって決まります。

この選択に基づいて、aws_assume_role、またはaws_api_keyaws_secret_keyの次のフィールドを選択的に表示/非表示にします。 これはngIf属性を使用して行います。

TIP

ほとんどのAWSサービスは同じ認証を使用するため、前の例と同じコネクションフィールドを使用できます。

さらにフィールドを追加する場合は、少なくともnameキーを指定する必要があります。 optionalhintcontrol_typeなどの追加属性を使用すると、これらのフィールドの他の側面をカスタマイズできます。 Client Secretなどの機密情報には、control_typeとしてpasswordを使用してください。

Workatoの入力フィールドを定義する方法を確認します。

ステップ2 - AWS署名の生成

他の認証方法と比較して、AWSでは現在時刻が署名の構成要素であるため、リクエストごとに一意の署名が必要です。 そのため、一般的に適用する認証情報がないため、コネクタではapply lambdaを使用しないでください。

代わりに、API呼び出しを行う前にaws.generate_signatureメソッドを使用して、有効なURLと署名を取得する必要があります。 この例では、S3にGETリクエストを行うlist_bucketsメソッドを作成していることがわかります。

ruby
    list_buckets: lambda do |connection|
      signature = aws.generate_signature(
        # The connection object defined earlier.
        connection: connection,
        # The internal name of the AWS service you are targeting
        service: "s3",
        # The AWS service region you are targeting.
        # For services with a globally unique endpoint such as IAM, use us-east-1.
        region: connection["aws_region"],
        # The host of the API url.
        # Optional and defaults to "#{service}.#{region}.amazonaws.com".
        # In some cases like AWS API Gateway and AWS IAM, your host may not follow this standard and require you to override the host.
        host: "s3.dualstack.#{connection['aws_region']}.amazonaws.com",
        # The relative path of the endpoint. Optional and defaults to "/"
        path: "/",
        # The verb used for the request. Optional and defaults to "GET"
        method: "GET",
        # The query parameters for the request. Optional and defaults to {}
        params: { "list-type" => 2, "max-keys" => 1000 },
        # The headers for the request. Optional and defaults to {}
        headers: {},
        # The payload for the request. Optional and defaults to ""
        payload: ""
      )
      url = signature[:url]
      headers = signature[:headers]

      response = get(url).headers(headers).response_format_xml

      files = response.dig("ListBucketResult", 0, "Contents")
      files = Array.wrap(files).map do |content|
        content.each_with_object({}) do |(k, v), obj|
          obj[k] = Array.wrap(v).dig(0, "content!")
        end
      end

      { "files" => files }
    end

ステップ3 - コネクションのテスト

前に定義したメソッドを使用すると、テストでこのメソッドを呼び出してユーザーの認証情報を検証できます。

ruby
  test: lambda do |connection|
    call(:list_buckets, connection)
  end,

トラブルシューティングのヒント

コネクションをテストしても、AWS署名が正しく検証されない場合があります。 代わりに、前の例のようにシンプルなAPIリクエストをメソッドでラップし、初期Development中にコネクションをスタブ化してアクションをテストします。

ruby
{
  title: "Sample AWS S3 Connector",

  connection: {
    fields: [
      #  Same fields as earlier
    ],

    authorization: {
      type: "custom_auth"
    }
  },

  test: lambda do |connection|
    true
  end,

  actions: {
    sample_action: {
      execute: lambda do |connection|
        call(:list_buckets, connection)
      end
    }
  },

  methods: {
    list_buckets: lambda do |connection|
      # Method from earlier
    end
  }
}

"sample_action"アクションをテストすると、接続先のWorkato SDKフレームワークまたはAWS APIによって発生したエラーをデバッグするためのより優れたInsightsを得られます。

コネクションSDKリファレンス

SDKリファレンスで、connectionキー内で使用できるキーについて確認します。

Last updated: