Alibaba Cloud SDK for Java では、認証を簡素化するための認証情報プロバイダーライブラリが使用されます。本トピックでは、アプリケーション向けに AccessKey ペア、セキュリティトークンサービス (STS) トークン、およびその他の認証情報タイプを安全に管理するための、認証情報プロバイダーのインストールと構成方法について説明します。
背景情報
認証情報とは、ユーザーの ID を検証するための一連の情報です。システムにログインするには、ユーザーが有効な認証情報を提供する必要があります。一般的な認証情報の種類は以下のとおりです。
AccessKey (AK):Alibaba Cloud アカウントまたは RAM ユーザーの永続的な認証情報であり、AccessKey ID と AccessKey Secret から構成されるキーペアです。
STS トークン:Alibaba Cloud RAM ロール向けの一時的なセキュリティ認証情報です。有効期間およびアクセス権限をカスタマイズできます。詳細については、「STS とは」をご参照ください。
ベアラートークン:認証および権限付与に使用されるトークンの一種です。
前提条件
認証情報ツールは PHP 5.6 以降を必要とします。cURL 拡張機能の使用を強く推奨しており、TLS バックエンドで cURL 7.16.2 以降をコンパイルすることをお勧めします。
Alibaba Cloud SDK V2.0 が必要です。
認証情報のインストール
グローバルにインストール済みの Composer を使用している場合、プロジェクトディレクトリで次のコマンドを実行して、Alibaba Cloud Credentials for PHP を依存関係としてインストールします。
composer require alibabacloud/credentialsすべての認証情報タイプをサポートするために、依存関係の最新リリース版を使用してください。
リリースされたすべてのバージョンの一覧については、「CHANGELOG.md」をご参照ください。
認証情報ツールの パラメーター
認証情報ツールの構成パラメーターは、AlibabaCloud\Credentials\Credential\Config で定義されています。認証情報のタイプは、必須の type パラメーターで指定します。認証情報のタイプを指定した後は、対応するパラメーターを選択する必要があります。下記の表では、type の取り得る値と、各認証情報タイプでサポートされるパラメーターについて説明しています。表中で、√ は必須パラメーター、- は任意パラメーター、× は非対応パラメーターを示します。
表に記載されていない認証情報タイプまたはパラメーターは使用しないでください。
パラメーター | access_key | sts | ram_role_arn | ecs_ram_role | oidc_role_arn | credentials_uri | bearer |
accessKeyId:AccessKey ID。 | √ | √ | √ | × | × | × | × |
accessKeySecret:AccessKey Secret。 | √ | √ | √ | × | × | × | × |
securityToken:セキュリティトークンサービス (STS) トークン。 | × | √ | - | × | × | × | × |
roleArn:RAM ロールの Alibaba Cloud Resource Name (ARN)。 | × | × | √ | × | √ | × | × |
roleSessionName:カスタムセッション名。デフォルト値は | × | × | - | × | - | × | × |
roleName:RAM ロールの名前。 | × | × | × | - | × | × | × |
disableIMDSv1:セキュリティ強化モードを強制的に適用するかどうかを指定します。デフォルト値は | × | × | × | - | × | × | × |
bearerToken:ベアラートークン。 | × | × | × | × | × | × | √ |
policy:カスタムポリシー。 | × | × | - | × | - | × | × |
roleSessionExpiration:セッションの有効期限 (秒単位)。デフォルト値は 3600 です。 | × | × | - | × | - | × | × |
oidcProviderArn:OIDC ID プロバイダーの Alibaba Cloud Resource Name (ARN)。 | × | × | × | × | √ | × | × |
oidcTokenFilePath:OIDC トークンのファイルパス。 | × | × | × | × | √ | × | × |
externalId:RAM ロールの外部 ID。このパラメーターにより、混乱した代理人 (confused deputy) 問題を防止できます。詳細については、「外部 ID を使用した混乱した代理人問題の防止」をご参照ください。 | × | × | - | × | × | × | × |
credentialsURI:認証情報の URI。 | × | × | × | × | × | √ | × |
STSEndpoint:セキュリティトークンサービス (STS) のエンドポイント。VPC エンドポイントおよびパブリックエンドポイントの両方がサポートされています。有効な値の一覧については、「エンドポイント」をご参照ください。デフォルト値は | × | × | - | × | - | × | × |
timeout:HTTP 読み取りタイムアウト (ミリ秒単位)。デフォルト値は 5000 です。 | × | × | - | - | - | - | × |
connectTimeout:HTTP 接続タイムアウト (ミリ秒単位)。デフォルト値は 10000 です。 | × | × | - | - | - | - | × |
認証情報クライアントの初期化
プロジェクト内に AccessKey をプレーンテキスト形式で保存すると、セキュリティリスクが発生します。コードリポジトリのアクセス許可が誤って設定されている場合、AccessKey が漏洩し、アカウント内のすべてのリソースが危険にさらされる可能性があります。そのため、AccessKey は環境変数または設定ファイルに保存してください。
認証情報ツールを使用する際は、シングルトンパターンを採用してください。これにより、ツールに組み込まれた認証情報キャッシュ機能が有効になり、頻繁な API 呼び出しによる速度制限を回避し、複数のインスタンス作成によるリソースの無駄を防ぐことができます。詳細については、「セッション認証情報の自動更新メカニズム」をご参照ください。
方法 1:デフォルトの認証情報プロバイダーチェーンの使用
パラメーターを指定せずに初期化された認証情報クライアントは、デフォルトの認証情報プロバイダーチェーンを使用します。「デフォルトの認証情報プロバイダーチェーン」を参照して、認証情報の読み込み方法をご確認ください。
<?php
use AlibabaCloud\Credentials\Credential;
// vendor ディレクトリ内の autoload.php ファイルを読み込んで、Composer のオートローダーを有効化します。
require_once 'vendor/autoload.php';
// パラメーターを指定しません。
$credClient = new Credential();
$credential = $credClient->getCredential();
$credential->getAccessKeyId();
$credential->getAccessKeySecret();
API 呼び出しの例
方法 2:AccessKey の使用
<?php
use AlibabaCloud\Credentials\Credential;
use AlibabaCloud\Credentials\Credential\Config;
// Composer のオートローダーを有効化します。
require_once 'vendor/autoload.php';
$credConfig = new Config([
'type' => 'access_key',
'accessKeyId' => getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'),
'accessKeySecret' => getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
]);
$credClient = new Credential($credConfig);
$credential = $credClient->getCredential();
$credential->getAccessKeyId();
$credential->getAccessKeySecret();
API の例
方法 3:STS トークンの使用
<?php
use AlibabaCloud\Credentials\Credential;
use AlibabaCloud\Credentials\Credential\Config;
// Composer のオートローダーを有効化するために 'vendor/autoload.php' を含めます。
require_once 'vendor/autoload.php';
$credConfig = new Config([
'type' => 'sts',
// 環境変数から AccessKey ID を取得します。
'accessKeyId' => getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'),
// 環境変数から AccessKey Secret を取得します。
'accessKeySecret' => getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
// 環境変数からセキュリティトークンを取得します。
'securityToken' => getenv('ALIBABA_CLOUD_SECURITY_TOKEN'),
]);
$credClient = new Credential($credConfig);
$credential = $credClient->getCredential();
$credential->getAccessKeyId();
$credential->getAccessKeySecret();
$credential->getSecurityToken();API の例
方法 4:AccessKey と RAM ロール ARN の併用
この方法では、内部的に STS トークンが使用されます。認証情報ツールは、RAM ロールの Alibaba Cloud Resource Name (ARN) を使用して STS からこのトークンを取得します。また、policy を割り当てることで、生成されたセッションの権限を制限できます。
<?php
use AlibabaCloud\Credentials\Credential;
use AlibabaCloud\Credentials\Credential\Config;
// Composer のオートローダーを含めます。
require_once 'vendor/autoload.php';
$credConfig = new Config([
'type' => 'ram_role_arn',
'accessKeyId' => getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'),
'accessKeySecret' => getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
// 偽装する RAM ロールの ARN。ALIBABA_CLOUD_ROLE_ARN 環境変数で設定可能です。例:acs:ram::123456789012****:role/adminrole。
'roleArn' => '<RoleArn>',
// カスタムロールセッション名。ALIBABA_CLOUD_ROLE_SESSION_NAME 環境変数で設定可能です。
'roleSessionName' => '<RoleSessionName>',
// オプション。セッションの権限をさらに制限するポリシー。例:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}。
'policy' => '<Policy>',
// オプション。セッションの有効期限 (秒単位)。デフォルト値:3600。
'roleSessionExpiration' => 3600,
]);
$credClient = new Credential($credConfig);
$credential = $credClient->getCredential();
$credential->getAccessKeyId();
$credential->getAccessKeySecret();
$credential->getSecurityToken();API 呼び出しの例
方法 5:ECS インスタンス RAM ロールの使用
ECS インスタンスおよび ECI インスタンスの両方にインスタンス RAM ロールをアタッチできます。これらのインスタンス上で実行されるアプリケーションは、認証情報ツールを使用して、ロールの STS トークンを自動的に取得し、認証情報クライアントを初期化できます。
デフォルトでは、認証情報ツールは、まずセキュリティ強化モード (IMDSv2) で ECS メタデータサービスにアクセスしようと試みます。この試行が失敗した場合、ツールは通常モードにフォールバックしてアクセス認証情報を取得します。disableIMDSv1 パラメーターまたは ALIBABA_CLOUD_IMDSV1_DISABLE 環境変数を設定することで、このフォールバック動作をカスタマイズできます。
値が false (デフォルト) の場合、ツールは失敗時に通常モードにフォールバックします。
値が true の場合、ツールはセキュリティ強化モードのみを使用し、失敗時にフォールバックせずに例外をスローします。
サーバー側の構成によって、サーバーが IMDSv2 をサポートするかどうかが決まります。
ECS メタデータからの認証情報アクセスを無効にするには、環境変数 ALIBABA_CLOUD_ECS_METADATA_DISABLED=true を設定します。
セキュリティ強化モードでの一時的認証情報の取得には、Credentials バージョン 1.2.0 以降が必要です。
ECS インスタンスメタデータの詳細については、「インスタンスメタデータの取得」をご参照ください。
ECS または ECI インスタンスに RAM ロールを割り当てる手順については、「インスタンス RAM ロール」および「API オペレーションを呼び出してインスタンス RAM ロールを使用する」をご参照ください。
<?php
use AlibabaCloud\Credentials\Credential;
use AlibabaCloud\Credentials\Credential\Config;
// vendor ディレクトリ内の autoload.php ファイルを読み込んで、Composer のオートローディングを有効化します。
require_once 'vendor/autoload.php';
$credConfig = new Config([
'type' => 'ecs_ram_role',
// オプション。ECS RAM ロールの名前。指定しない場合、ロール名は自動的に取得されます。このパラメーターを指定すると、リクエスト数を削減できます。ALIBABA_CLOUD_ECS_METADATA 環境変数を使用してロール名を設定することもできます。
'roleName' => '<RoleName>',
// オプション。デフォルト値は false です。true に設定すると、セキュリティ強化モードが強制的に適用されます。false の場合、ツールはまずセキュリティ強化モードで認証情報を取得しようとして、失敗した場合は通常モード (IMDSv1) にフォールバックします。
// 'disableIMDSv1' => true,
]);
$credClient = new Credential($credConfig);
$credential = $credClient->getCredential();
$credential->getAccessKeyId();
$credential->getAccessKeySecret();
$credential->getSecurityToken();API 呼び出し
方法 6:OIDCRoleArn の使用
OIDC 認証プロトコルを使用し、OIDC ID プロバイダー用の RAM ロールを作成している場合は、OIDC ID プロバイダーの ARN、OIDC トークン、および RAM ロールの ARN を認証情報ツールに渡します。このツールは、自動的に AssumeRoleWithOIDC API を呼び出して RAM ロールの STS トークンを取得し、それをアクセス認証情報として使用します。これらの認証情報は、自動リフレッシュをサポートしています。詳細については、「セッション認証情報の自動リフレッシュメカニズム」をご参照ください。たとえば、RRSA が有効になっている ACK クラスターでアプリケーションを実行すると、認証情報ツールは Pod の環境変数から OIDC 構成を読み取り、AssumeRoleWithOIDC API を呼び出してサービスロールの STS トークンを取得します。これにより、アプリケーションは Alibaba Cloud サービスにアクセスできます。
<?php
use AlibabaCloud\Credentials\Credential;
use AlibabaCloud\Credentials\Credential\Config as CredentialConfig;
// vendor ディレクトリ内の autoload.php ファイルを読み込んで、Composer のオートローディングを有効化します。
require_once 'vendor/autoload.php';
// OIDC ID プロバイダー経由で RAM ロールを偽装するための認証情報クライアントを初期化します。
$credConfig = new CredentialConfig([
// 認証情報のタイプ。
'type' => 'oidc_role_arn',
// OIDC プロバイダー ARN。ALIBABA_CLOUD_OIDC_PROVIDER_ARN 環境変数でも設定可能です。
'oidcProviderArn' => '<OidcProviderArn>',
// OIDC トークンファイルのパス。ALIBABA_CLOUD_OIDC_TOKEN_FILE 環境変数でも設定可能です。
'oidcTokenFilePath' => '<OidcTokenFilePath>',
// 偽装する RAM ロールの ARN。ALIBABA_CLOUD_ROLE_ARN 環境変数でも設定可能です。例:acs:ram::123456789012****:role/adminrole。
'roleArn' => '<RoleArn>',
// カスタムロールセッション名。ALIBABA_CLOUD_ROLE_SESSION_NAME 環境変数でも設定可能です。
'roleSessionName' => '<RoleSessionName>',
// オプション。より制限の厳しいセッションポリシー。例:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}。
'policy' => '<Policy>',
// オプション。セッションの有効期限 (秒単位)。
'roleSessionExpiration' => 3600,
]);
$credClient = new Credential($credConfig);
$credential = $credClient->getCredential();
$credential->getAccessKeyId();
$credential->getAccessKeySecret();
$credential->getSecurityToken();
API 呼び出し の例
方法 7:URI 認証情報
STS サービスをカプセル化し、その URI を公開することで、外部サービスが STS トークンを取得できます。この方法により、AccessKey などの機密情報を公開するリスクを低減できます。認証情報ツールは、指定した URI から STS トークンを取得し、これをアクセス認証情報として使用します。この方法で取得した認証情報は自動更新をサポートします。詳細については、「セッション型認証情報の自動更新」をご参照ください。
<?php
namespace AlibabaCloud\SDK\Sample;
use AlibabaCloud\Credentials\Credential;
use AlibabaCloud\Credentials\Credential\Config;
// Composer のオートローダーを有効化するために vendor/autoload.php ファイルを含めます。
require_once 'vendor/autoload.php';
// URI 認証情報を使用して認証情報クライアントを初期化します。
$credConfig = new Config([
// 認証情報のタイプ。
'type' => 'credentials_uri',
// 認証情報 URI。例:http://local_or_remote_uri/。あるいは ALIBABA_CLOUD_CREDENTIALS_URI 環境変数を設定します。
'credentialsURI' => '<CredentialsUri>',
]);
$credClient = new Credential($credConfig);
$credential = $credClient->getCredential();
$credential->getAccessKeyId();
$credential->getAccessKeySecret();
$credential->getSecurityToken();URI は、以下の要件を満たす必要があります。
GET リクエストをサポートすること。
200 ステータスコードを返すこと。
レスポンスボディが、以下のフィールドを含む JSON オブジェクトであること:
{ "AccessKeyId": "AccessKeyId", "AccessKeySecret": "AccessKeySecret", "Expiration": "2021-09-26T03:46:38Z", "SecurityToken": "SecurityToken" }
API 呼び出し
方法 8:ベアラートークンの使用
<?php
use AlibabaCloud\Credentials\Credential;
use AlibabaCloud\Credentials\Credential\Config;
// Composer のオートローダーを読み込みます。
require_once 'vendor/autoload.php';
$credConfig = new Config([
'type' => 'bearer',
// ベアラートークンを設定します。
'bearerToken' => '<BearerToken>',
]);
$credClient = new Credential($credConfig);
$credential = $credClient->getCredential();
$credential->getBearerToken();API の例
デフォルトの認証情報プロバイダーチェーン
開発環境と本番環境で異なるタイプの認証情報を使用する場合、通常は各環境に対応する条件付きコードを記述する必要があります。デフォルトの認証情報プロバイダーチェーンにより、この作業が簡素化され、単一のコードベースを使用して、外部構成によって認証情報の取得を制御できます。パラメーターを指定せずに $credential = new Credential(); を使用して認証情報クライアントを初期化すると、Alibaba Cloud SDK は以下のソースから順次認証情報を検索します。
1. 環境変数
2. OIDC ID プロバイダーの RAM ロール
3. config.json ファイル
4. ECS インスタンス RAM ロール
それより優先度の高い認証情報が見つからない場合、SDK は ECS インスタンスにアタッチされた RAM ロールから認証情報を取得しようと試みます。デフォルトでは、SDK は拡張モード (IMDSv2) で ECS メタデータサービスにアクセスして、ECS インスタンス RAM ロールの STS トークンを取得します。このプロセスには 2 回のリクエストが含まれます。SDK はまず、メタデータサービスに問い合わせてロール名を取得し、その後、認証情報を取得します。この処理を 1 回のリクエストに減らすには、ALIBABA_CLOUD_ECS_METADATA 環境変数を設定して、インスタンス RAM ロール名を直接指定できます。拡張モードでエラーが発生した場合、SDK は通常モードにフォールバックします。また、ALIBABA_CLOUD_IMDSV1_DISABLE 環境変数を設定して、このフォールバック動作を制御することもできます。
値が
falseの場合、SDK は通常モードにフォールバックして認証情報を取得します。値が
trueの場合、拡張モードのみが使用され、失敗時に例外がスローされます。
IMDSv2 のサポートは、サーバー構成によって異なります。
ECS メタデータからの認証情報アクセスを無効にするには、ALIBABA_CLOUD_ECS_METADATA_DISABLED 環境変数を true に設定します。
ECS インスタンスメタデータの詳細については、「インスタンスメタデータ」をご参照ください。
ECS または ECI インスタンスに RAM ロールをアタッチする手順については、「RAM ロールの作成」および「ECI インスタンスへのインスタンス RAM ロールの付与」をご参照ください。
5. 認証情報 URI
カスタム認証情報プロバイダーチェーン
デフォルトの検索順序をオーバーライドするには、カスタム認証情報プロバイダーチェーンを使用できます。また、クロージャーとしてプロバイダーを渡すこともできます。
<?php
use AlibabaCloud\Credentials\Providers\ChainProvider;
ChainProvider::set(
ChainProvider::ini(),
ChainProvider::env(),
ChainProvider::instance()
);セッション認証情報 の自動更新
認証情報ツールは、ram_role_arn、ecs_ram_role、oidc_role_arn、および credentials_uri など、セッション認証情報に対して組み込みの自動更新メカニズムを提供します。認証情報クライアントが初めて認証情報を取得すると、認証情報ツールはそれをキャッシュします。その後の操作では、クライアントがキャッシュから認証情報を取得します。キャッシュされた認証情報が有効期限切れになると、クライアントは自動的に新しい認証情報を取得してキャッシュを更新します。
ecs_ram_role 認証情報の場合、認証情報ツールは有効期限が切れる 15 分前に、認証情報を積極的に更新します。
この例では、シングルトンパターンを使用して認証情報クライアントを作成します。自動更新メカニズムを実証するために、異なる間隔で認証情報を取得し、OpenAPI 呼び出しを実行してその有効性を検証します。
<?php
namespace Sample;
require_once 'vendor/autoload.php';
use AlibabaCloud\Credentials\Credential;
use AlibabaCloud\Credentials\Credential\Config as CredentialConfig;
use AlibabaCloud\SDK\Ecs\V20140526\Ecs;
use AlibabaCloud\SDK\Ecs\V20140526\Models\DescribeRegionsRequest;
use Darabonba\OpenApi\Models\Config as OpenApiConfig;
use RuntimeException;
class Sample
{
/**
* @var Credential|null
*/
private static $credentialInstance = null;
/**
* @return Credential
* @throws RuntimeException
*/
private static function getCredentialClient(): Credential
{
if (self::$credentialInstance === null) {
try {
$config = new CredentialConfig([
'type' => 'ram_role_arn',
'accessKeyId' => getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'),
'accessKeySecret' => getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
'roleArn' => getenv('ALIBABA_CLOUD_ROLE_ARN'),
'roleSessionName' => 'RamRoleArnTest',
'roleSessionExpiration' => 3600,
]);
self::$credentialInstance = new Credential($config);
} catch (\Exception $e) {
throw new RuntimeException("Credential initialization failed: " . $e->getMessage(), 0, $e);
}
}
return self::$credentialInstance;
}
/**
* @var Ecs|null
*/
private static $ecsClientInstance = null;
/**
* @return Ecs
* @throws RuntimeException
*/
private static function getEcsClient(): Ecs
{
if (self::$ecsClientInstance === null) {
try {
$config = new OpenApiConfig([
'credential' => self::getCredentialClient(),
'endpoint' => 'ecs.cn-hangzhou.aliyuncs.com'
]);
self::$ecsClientInstance = new Ecs($config);
} catch (\Exception $e) {
throw new RuntimeException("ECS client initialization failed: " . $e->getMessage(), 0, $e);
}
}
return self::$ecsClientInstance;
}
public static function main(): void
{
$task = function () {
// 認証情報を取得して出力します。
$credentialClient = self::getCredentialClient();
$credential = $credentialClient->getCredential();
echo date('c') . PHP_EOL;
echo "AK ID: {$credential->accessKeyId}" . PHP_EOL;
echo "AK シークレット: {$credential->accessKeySecret}" . PHP_EOL;
echo "STS トークン: {$credential->securityToken}" . PHP_EOL;
// 認証情報が有効であるかを確認するために ECS API 操作を呼び出します。
$ecsClient = self::getEcsClient();
$request = new DescribeRegionsRequest();
try {
$response = $ecsClient->describeRegions($request);
echo sprintf("呼び出し結果: %d" . PHP_EOL, $response->statusCode);
} catch (\Exception $e) {
throw new RuntimeException("ECS クライアントの実行に失敗しました: " . $e->getMessage(), 0, $e);
}
};
call_user_func($task); // 直ちに操作を呼び出します。
sleep(600); // 600 秒後に操作を呼び出します。
call_user_func($task);
sleep(3600); // 3,600 秒後に操作を呼び出します。
call_user_func($task);
sleep(100); // 100 秒後に操作を呼び出します。
call_user_func($task);
}
}
// main 関数を実行します。
Sample::main();