このドキュメントでは、Alibaba Cloud IDaaS (EIAM) におけるマシンツーマシン (M2M) クライアントトークン呼び出しの例を説明します。OAuth 2.0 クライアント資格情報フローを使用してアクセストークンを取得し、安全なシステム間認証のために API を呼び出す方法について説明します。
呼び出し例
認証方式: client_secret_basic
リクエストメソッド: POST
ヘッダーパラメーター
パラメーター
タイプ
説明
例
Authorization
文字列
このパラメーターの値は、clientId と clientSecret を clientId:clientSecret のフォーマットで結合し、Base64 でエンコードした文字列です。
YXBwX201ZG9vemVzbm81Mmtxxxxxxxxx
Content-Type
文字列
静的フィールド: application/x-www-form-urlencoded
application/x-www-form-urlencoded
リクエストパラメーター
パラメーター
タイプ
説明
例
grant_type
文字列
静的フィールド: client_credentials。
client_credentials
scope
文字列
スコープに基づいて権限をリクエストします。値はスペースで区切られた文字列です。各権限のフォーマットは resourceServerIdentifier|scope です。例:
resourceServerIdentifier が api://api.xxxxx.com で、スコープが read:file の場合。
最終的な結果は次のようになります: api://api.xxxxx.com|read:file
{resourceServerIdentifier}|.all を使用して、すべての承認済みスコープを取得できます。
api://api.xxxxx.com|read:file
client_id
文字列
アプリケーション ID。
リクエストの例
curl --location --request POST 'https://XXXX.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \ --header 'Authorization: Basic YXBwX201ZG9vemVxxxxxx' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'api://api.xxxxx.com|read:file'レスポンスパラメーター
パラメーター
タイプ
任意
説明
access_token
文字列
いいえ
トークンの値。
expires_in
Long
いいえ
有効期間 (秒)。
expires_at
Long
番号
有効期限。これは UNIX タイムスタンプ (秒) です。
token_type
文字列
いいえ、そうではありません。
トークンのタイプ。
レスポンスの例
{ "token_type": "Bearer", "access_token": "AT8csE2******HBkxxHUG", "expires_in": 3600, "expires_at": 1733710213 }
認証方式: client_secret_post
リクエストメソッド: POST
ヘッダーパラメーター
パラメーター
タイプ
説明
例
Content-Type
文字列
静的フィールド: application/x-www-form-urlencoded
application/x-www-form-urlencoded
リクエストパラメーター
パラメーター
タイプ
説明
例
grant_type
文字列
静的フィールド: client_credentials。
client_credentials
client_id
文字列
アプリケーション ID。
client_secret
文字列
アプリケーションシークレット。
scope
文字列
スコープに基づいて権限をリクエストします。値はスペースで区切られた文字列です。各権限のフォーマットは resourceServerIdentifier|scope です。例:
resourceServerIdentifier が api://api.xxxxx.com で、スコープが read:file の場合。
最終的な結果は次のようになります: api://api.xxxxx.com|read:file
現在のクライアントに承認されているすべてのスコープは、
{resourceServerIdentifier}|.allを使用して取得できます。api://api.xxxxx.com|read:file
リクエストの例
curl --location --request POST 'https://XXXX.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'client_id=app_m5doozesno52kbqrqpw3XXXX' \ --data-urlencode 'client_secret=CS5v3F4Cy8hyDmFPJtAuyHDTUdR8i88GcgcXXXXX' \ --data-urlencode 'scope=api://api.xxxxx.com|read:file'レスポンスの例
{ "token_type": "Bearer", "access_token": "AT8csE2s*****HBkxxHUG", "expires_in": 3600, "expires_at": 1733710213 }
認証方式: client_secret_jwt
リクエストメソッド: POST
ヘッダーパラメーター
パラメーター
タイプ
説明
例
Content-Type
文字列
静的フィールド: application/x-www-form-urlencoded
application/x-www-form-urlencoded
リクエストパラメーター
パラメーター
タイプ
説明
例
grant_type
文字列
静的フィールド: client_credentials。
client_credentials
client_id
文字列
アプリケーション ID。
client_assertion_type
文字列
クライアントアサーションタイプ。静的フィールド: urn:ietf:params:oauth:client-assertion-type:jwt-bearer。
client_assertion
文字列
client_secret を使用してクライアントによって発行された署名。署名は JWT フォーマットで、HS256 アルゴリズムを使用します。詳細については、「付録 2」をご参照ください。
scope
文字列
スコープに基づいて権限をリクエストします。値はスペースで区切られた文字列です。各権限のフォーマットは resourceServerIdentifier|scope です。例:
resourceServerIdentifier が api://api.xxxxx.com で、スコープが read:file の場合。
最終的な結果は次のようになります: api://api.xxxxx.com|read:file
{resourceServerIdentifier}|.allを使用して、すべての承認済みスコープを取得できます。api://api.xxxxx.com|read:file
リクエストの例
curl --request POST \ --url 'https://XXXX.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'client_id={{clientId}}' \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \ --data-urlencode 'client_assertion={{JwtToken}}' \ --data-urlencode 'scope=api://api.xxxxx.com|read:file'レスポンスの例
{ "token_type": "Bearer", "access_token": "AT8csE2******kxxHUG", "expires_in": 3600, "expires_at": 1733710213 }
認証方式: private_key_jwt
リクエストメソッド: POST
ヘッダーパラメーター
パラメーター
タイプ
説明
例
Content-Type
文字列
静的フィールド: application/x-www-form-urlencoded
application/x-www-form-urlencoded
リクエストパラメーター
パラメーター
タイプ
説明
例
grant_type
文字列
静的フィールド: client_credentials。
client_credentials
client_id
文字列
アプリケーション ID。
client_assertion_type
文字列
クライアントアサーションタイプ。静的フィールド: urn:ietf:params:oauth:client-assertion-type:jwt-bearer。
client_assertion
文字列
秘密鍵を使用してクライアントによって発行された署名。署名は JWT フォーマットで、RS256 アルゴリズムを使用します。詳細については、「付録 1」をご参照ください。
scope
文字列
スコープに基づいて権限をリクエストします。値はスペースで区切られた文字列です。各権限のフォーマットは resourceServerIdentifier|scope です。例:
resourceServerIdentifier が api://api.xxxxx.com で、スコープが read:file の場合。
最終的な結果は次のようになります: api://api.xxxxx.com|read:file
現在のクライアントに承認されているすべてのスコープは、{resourceServerIdentifier}|.all を使用して取得できます。
api://api.xxxxx.com|read:file
リクエストの例
curl --request POST \ --url 'https://XXXX.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'client_id={{clientId}}' \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \ --data-urlencode 'client_assertion={{JwtToken}}' \ --data-urlencode 'scope=api://api.xxxxx.com|read:file'レスポンスの例
{ "token_type": "Bearer", "access_token": "AT8csE2*******BkxxHUG", "expires_in": 3600, "expires_at": 1733710213 }
認証方式: OIDC フェデレーション認証
リクエストメソッド: POST
ヘッダーパラメーター
パラメーター
タイプ
説明
例
Content-Type
文字列
静的フィールド: application/x-www-form-urlencoded
application/x-www-form-urlencoded
リクエストパラメーター
パラメーター
タイプ
説明
例
grant_type
文字列
静的フィールド: client_credentials。
client_credentials
client_id
文字列
アプリケーション ID。
client_assertion_type
文字列
クライアントアサーションタイプ。静的フィールド: urn:cloud:idaas:params:oauth:client-assertion-type:id-token-bearer。
client_assertion
文字列
クライアントが使用する OIDC トークン (JWT フォーマット)。
scope
文字列
スコープに基づいて権限をリクエストします。値はスペースで区切られた文字列です。各権限のフォーマットは resourceServerIdentifier|scope です。例:
resourceServerIdentifier が api://api.xxxxx.com で、スコープが read:file の場合。
最終的な出力は次のようになります: api://api.xxxxx.com|read:file
現在のクライアントに承認されているすべてのスコープを取得するには、{resourceServerIdentifier}|.all を使用します。
api://api.xxxxx.com|read:file
application_federated_credential_name
文字列
アプリケーションのフェデレーション資格情報の名前。
aliyun_ack
リクエストの例
curl --request POST \ --url 'https://xxxxx.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \ --header 'content-type: application/x-www-form-urlencoded' \ --data-urlencode 'client_id=app_xxxxxx' \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'scope=api://api.xxxxx.com|.all' \ --data-urlencode 'application_federated_credential_name=xxxxxx' \ --data-urlencode 'client_assertion=xxxxx.xxxxx.xxxxx' \ --data-urlencode 'client_assertion_type=urn:cloud:idaas:params:oauth:client-assertion-type:id-token-bearer'レスポンスパラメーター
パラメーター
タイプ
任意
説明
access_token
文字列
いいえ
アクセストークンの値。
expires_in
Long
いいえ
有効期間 (秒)。
expires_at
Long
いいえ、そうではありません。
有効期限。これは UNIX タイムスタンプ (秒) です。
token_type
文字列
いいえ、そうではありません。
アクセストークンのタイプ。
レスポンスの例
{ "token_type": "Bearer", "access_token": "AT8csE2se******BkxxHUG", "expires_in": 3600, "expires_at": 1733710213 }
認証方式: PKCS#7 署名認証
リクエストメソッド: POST
ヘッダーパラメーター
パラメーター
タイプ
説明
例
Content-Type
文字列
静的フィールド: application/x-www-form-urlencoded
application/x-www-form-urlencoded
リクエストパラメーター
パラメーター
タイプ
説明
例
grant_type
文字列
静的フィールド: client_credentials。
client_credentials
client_id
文字列
アプリケーション ID。
client_assertion_type
文字列
クライアントアサーションタイプ。静的フィールド: urn:cloud:idaas:params:oauth:client-assertion-type:pkcs7-bearer。
client_assertion
文字列
PKCS#7 署名の値。
scope
文字列
スコープに基づいて権限をリクエストします。値はスペースで区切られた文字列です。各権限のフォーマットは resourceServerIdentifier|scope です。例:
resourceServerIdentifier が api://api.xxxxx.com で、スコープが read:file の場合。
最終的な結果は次のようになります: api://api.xxxxx.com|read:file
{resourceServerIdentifier}|.all を使用して、すべての承認済みスコープを取得できます。
api://api.xxxxx.com|read:file
application_federated_credential_name
文字列
アプリケーションのフェデレーション資格情報の名前。
aliyun_ecs
リクエストの例
curl --request POST \ --url 'https://xxxxx.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \ --header 'content-type: application/x-www-form-urlencoded' \ --data-urlencode 'client_id=app_xxxxx' \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'scope=api://api.xxxxx.com|.all' \ --data-urlencode 'application_federated_credential_name=xxxxxx' \ --data-urlencode 'client_assertion=xxxxx' \ --data-urlencode 'client_assertion_type=urn:cloud:idaas:params:oauth:client-assertion-type:pkcs7-bearer'レスポンスパラメーター
パラメーター
タイプ
NULL 可能
説明
access_token
文字列
いいえ、そうではありません。
アクセストークンの値。
expires_in
Long
いいえ
有効期間 (秒)。
expires_at
Long
いいえ、そうではありません。
有効期限。これは UNIX タイムスタンプ (秒) です。
token_type
文字列
いいえ、そうではありません。
アクセストークンのタイプ。
レスポンスの例
{ "token_type": "Bearer", "access_token": "AT8csE2s******HBkxxHUG", "expires_in": 3600, "expires_at": 1733710213 }
認証方式: プライベート CA 証明書認証
リクエストメソッド: POST
ヘッダーパラメーター
パラメーター
タイプ
説明
例
Content-Type
文字列
静的フィールド: application/x-www-form-urlencoded。
application/x-www-form-urlencoded
リクエストパラメーター
パラメーター
タイプ
説明
例
grant_type
文字列
静的フィールド: client_credentials。
client_credentials
client_id
文字列
アプリケーション ID。
client_assertion_type
文字列
クライアントアサーションタイプ。静的フィールド: urn:cloud:idaas:params:oauth:client-assertion-type:x509-jwt-bearer。
client_assertion
文字列
private_key を使用してクライアントによって発行された JWT トークン。
scope
文字列
スコープに基づいて権限をリクエストします。値はスペースで区切られた文字列です。各権限のフォーマットは resourceServerIdentifier|scope です。例:
resourceServerIdentifier が api://api.xxxxx.com で、スコープが read:file の場合。
最終的な結果は次のようになります: api://api.xxxxx.com|read:file。
現在のクライアントに付与されているすべてのスコープを取得するには、次を使用します:
api://api.xxxxx.com|read:file
client_x509
文字列
エンドエンティティ証明書 (リーフ証明書)、つまりクライアント証明書です。
Base64 エンコードされた Distinguished Encoding Rules (DER)
-----BEGIN CERTIFICATE-----
xxxxxx
-----END CERTIFICATE-----
client_x509_chain
文字列
中間証明書 (中間 CA) のリスト。
DER フォーマットの Base64 エンコード文字列である必要があります。
改行を使用して複数の証明書を連結します。各証明書は次のフォーマットである必要があります:
-----BEGIN CERTIFICATE-----start -----END CERTIFICATE-----end-----BEGIN CERTIFICATE-----
xxxxxx1
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
xxxxxx1
-----END CERTIFICATE-----
application_federated_credential_name
文字列
アプリケーションのフェデレーション資格情報の名前。
private_ca
リクエストの例
curl --request POST \ --url 'https://xxxxx.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \ --header 'content-type: application/x-www-form-urlencoded' \ --data-urlencode 'client_id=app_xxxxx' \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'scope=api://api.xxxxx.com|.all' \ --data-urlencode 'application_federated_credential_name=xxxxx' \ --data-urlencode 'client_assertion=xxxxx' \ --data-urlencode 'client_assertion_type=urn:cloud:idaas:params:oauth:client-assertion-type:pkcs7-bearer'レスポンスパラメーター
パラメーター
タイプ
任意
説明
access_token
文字列
いいえ。
アクセストークンの値。
expires_in
Long
いいえ、そうではありません。
有効期間 (秒)。
expires_at
Long
いいえ
有効期限。これは UNIX タイムスタンプ (秒) です。
token_type
文字列
いいえ、そうではありません。
アクセストークンのタイプ。
レスポンスの例
{ "token_type": "Bearer", "access_token": "AT8csE2s******BkxxHUG", "expires_in": 3600, "expires_at": 1733710213 }
エラーコード
HTTP コード | エラー | エラーメッセージ | 説明 |
400 | invalid_request | 必須パラメーター変数: grant_type | リクエストに必須パラメーターがない、無効なパラメーター値が含まれている、パラメーターが複数回含まれている、またはその他の形式が正しくありません。 |
400 | authentication_required | 認証が必要です。許可されている認証方式: [client_secret_basic, client_secret_post, client_secret_jwt, private_key_jwt] | 認証方式が正しくありません。サポートされている認証方式は次のとおりです: client_secret_basic, client_secret_post, client_secret_jwt private_key_jwt。 |
400 | invalid_client_credential | 無効な client_assertion。理由: [expired] | client_assertion が無効です。トークンの有効期限が切れています。 |
400 | invalid_grant | 無効またはサポートされていない grant_type: authorization_code | grant_type はサポートされていません。 |
400 | invalid_scope | 無効なスコープ: http://www.example.com|read:file | リクエストされたスコープが無効、不明、または形式が正しくありません。 |
500 | internal_error | 予期しない内部エラー | 内部サーバーエラーが発生しました。 |
付録 1: Java を使用して JWT 署名を生成する (RS256 アルゴリズム)
この付録では、RS256 非対称暗号化アルゴリズムを使用して Java で JSON Web トークン (JWT) 署名を生成する方法の完全な例を示します。内容は次のとおりです:
Maven 依存関係
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.5</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency>Java コード例
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import java.security.Key; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.UUID; /** * @author fei.chen * @date 2025-02-24 16:17 */ public class JwtGenerator { private static final String PRIVATE_KEY = "your-private-key"; // 秘密鍵に置き換えます // アプリケーションの client_id を入力します private static final String ISSUER = "your_client_id"; // アプリケーションの client_id を入力します private static final String SUBJECT = "your_client_id"; // アプリケーションのトークンエンドポイントを入力します private static final String AUDIENCE = "your_token_endpoint"; public static void main(String[] args) throws Exception { // キー Key securityKey = RsaKeyConverter.getPrivateKeyFromString(PRIVATE_KEY); Map<String, Object> claims = new HashMap<>(); claims.put("jti", UUID.randomUUID().toString()); // リプレイ攻撃対策の jti // 有効期限を設定します。30 分を超えることはできません。 long expirationTime = 1000 * 60 * 30; Date expirationDate = new Date(System.currentTimeMillis() + expirationTime); // JWT を生成します String jwt = Jwts.builder() .setClaims(claims) .setIssuedAt(new Date()) .setExpiration(expirationDate) .setSubject(SUBJECT) .setIssuer(ISSUER) .setAudience(AUDIENCE) .signWith(securityKey, SignatureAlgorithm.RS256) .compact(); System.out.println("Generated JWT:"); System.out.println(jwt); } }import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; /** * @author fei.chen * @date 2025-02-24 16:51 */ public class RsaKeyConverter { public static PrivateKey getPrivateKeyFromString(String privateKeyStr) throws Exception { // PEM フォーマットのヘッダーとフッターを削除します String privateKeyPEM = privateKeyStr .replace("-----BEGIN PRIVATE KEY-----", "") .replace("-----END PRIVATE KEY-----", "") .replaceAll("\\s+", ""); // すべての空白文字を削除します // Base64 デコード byte[] encoded = Base64.getDecoder().decode(privateKeyPEM); // PKCS8EncodedKeySpec を使用して秘密鍵を生成します PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePrivate(keySpec); } public static PublicKey getPublicKeyFromString(String publicKeyStr) throws Exception { // PEM フォーマットのヘッダーとフッターを削除します String publicKeyPEM = publicKeyStr .replace("-----BEGIN PUBLIC KEY-----", "") .replace("-----END PUBLIC KEY-----", "") .replaceAll("\\s+", ""); // すべての空白文字を削除します // Base64 デコード byte[] encoded = Base64.getDecoder().decode(publicKeyPEM); // X509EncodedKeySpec を使用して公開鍵を生成します X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePublic(keySpec); } }
付録 2: Java を使用して JWT 署名を生成する (HS256 アルゴリズム)
この付録では、HS256 署名アルゴリズムを使用して Java で JSON Web トークン (JWT) 署名を生成する方法の完全な例を示します。この例には、以下が含まれます:
Maven 依存関係
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.5</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency>Java コード例
public class JwtGenerator { private static final String SECRET_KEY = "your_secret_key"; // シークレットキーに置き換えます // アプリケーションの client_id を入力します private static final String ISSUER = "your_client_id"; // アプリケーションの client_id を入力します private static final String SUBJECT = "your_client_id"; // アプリケーションのトークンエンドポイントを入力します private static final String AUDIENCE = "your_token_endpoint"; public static String generateJwt() throws Exception { SecretKey secretKey = Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); Map<String, Object> claims = new HashMap<>(); claims.put("jti", UUID.randomUUID().toString()); // リプレイ攻撃対策の jti // 有効期限を設定します。30 分を超えることはできません。 long expirationTime = 1000 * 60 * 30; Date expirationDate = new Date(System.currentTimeMillis() + expirationTime); // JWT を生成します String jwt = Jwts.builder() .setClaims(claims) .setIssuedAt(new Date()) .setExpiration(expirationDate) .setSubject(SUBJECT) .setIssuer(ISSUER) .setAudience(AUDIENCE) .signWith(secretKey, SignatureAlgorithm.HS256) .compact(); return jwt; } public static void main(String[] args) throws Exception{ // JWT を生成します String jwt = generateJwt(); System.out.println("Generated JWT: " + jwt); } }