All Products
Search
Document Center

Identity as a Service:M2M client token call examples

Last Updated:Oct 22, 2026

This topic provides call examples for M2M client tokens in Alibaba Cloud IDaaS (EIAM). It describes how to obtain an access token through the OAuth 2.0 Client Credentials Flow and call APIs to implement secure authentication between systems.

Call examples

Authentication method: client_secret_basic

  1. Request method: POST

  2. Header parameters:

    Parameter

    Type

    Description

    Example

    Authorization

    String

    The value is the Base64 encoding of clientId and clientSecret joined together. The join format is clientId:clientSecret.

    YXBwX201ZG9vemVzbm81Mmtxxxxxxxxx

    Content-Type

    String

    Fixed value: application/x-www-form-urlencoded

    application/x-www-form-urlencoded

  3. Request parameters:

    Parameter

    Type

    Description

    Example

    grant_type

    String

    Fixed value: client_credentials.

    client_credentials

    scope

    String

    You can request permissions by scope. String values are joined with spaces. The format is resourceServerIdentifier+"|"+scope. For example:

    resourceServerIdentifier is api://api.xxxxx.com, and scope is read:file.

    The final result is api://api.xxxxx.com|read:file.

    To obtain all scopes already authorized for the current client, use {resourceServerIdentifier}|.all

    api://api.xxxxx.com|read:file

    client_id

    string

    The application ID.

  4. Request example:

    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'
  5. Response parameters:

    Parameter

    Type

    Nullable

    Description

    access_token

    String

    No

    The token value.

    expires_in

    Long

    No

    The validity period, in seconds.

    expires_at

    Long

    No

    The expiration time, as a UNIX timestamp, in seconds.

    token_type

    String

    No

    The token type.

  6. Response example:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2s******kxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

Authentication method: client_secret_post

  1. Request method: POST

  2. Header parameters:

    Parameter

    Type

    Description

    Example

    Content-Type

    String

    Fixed value: application/x-www-form-urlencoded

    application/x-www-form-urlencoded

  3. Request parameters:

    Parameter

    Type

    Description

    Example

    grant_type

    String

    Fixed value: client_credentials.

    client_credentials

    client_id

    String

    The application ID.

    client_secret

    String

    The application secret.

    scope

    String

    You can request permissions by scope. String values are joined with spaces. The format is resourceServerIdentifier+"|"+scope. For example:

    resourceServerIdentifier is api://api.xxxxx.com, and scope is read:file.

    The final result is api://api.xxxxx.com|read:file.

    To obtain all scopes already authorized for the current client, use {resourceServerIdentifier}|.all

    api://api.xxxxx.com|read:file

  4. Request example:

    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'
  5. Response example:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2s******NHBkxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

Authentication method: client_secret_jwt

  1. Request method: POST

  2. Header parameters:

    Parameter

    Type

    Description

    Example

    Content-Type

    String

    Fixed value: application/x-www-form-urlencoded

    application/x-www-form-urlencoded

  3. Request parameters:

    Parameter

    Type

    Description

    Example

    grant_type

    String

    Fixed value: client_credentials.

    client_credentials

    client_id

    String

    The application ID.

    client_assertion_type

    String

    The client assertion type. Fixed value: urn:ietf:params:oauth:client-assertion-type:jwt-bearer.

    client_assertion

    String

    The signature issued by the client using client_secret, in JWT format. The signature algorithm is HS256. See Appendix 2.

    scope

    String

    You can request permissions by scope. String values are joined with spaces. The format is resourceServerIdentifier+"|"+scope. For example:

    resourceServerIdentifier is api://api.xxxxx.com, and scope is read:file.

    The final result is api://api.xxxxx.com|read:file.

    To obtain all scopes already authorized for the current client, use {resourceServerIdentifier}|.all

    api://api.xxxxx.com|read:file

  4. Request example:

    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'
  5. Response example:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2s******kxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

Authentication method: private_key_jwt

  1. Request method: POST

  2. Header parameters:

    Parameter

    Type

    Description

    Example

    Content-Type

    String

    Fixed value: application/x-www-form-urlencoded

    application/x-www-form-urlencoded

  3. Request parameters:

    Parameter

    Type

    Description

    Example

    grant_type

    String

    Fixed value: client_credentials.

    client_credentials

    client_id

    String

    The application ID.

    client_assertion_type

    String

    The client assertion type. Fixed value: urn:ietf:params:oauth:client-assertion-type:jwt-bearer.

    client_assertion

    String

    The signature issued by the client using the private key, in JWT format. The signature algorithm is RS256. See Appendix 1.

    scope

    String

    You can request permissions by scope. String values are joined with spaces. The format is resourceServerIdentifier+"|"+scope. For example:

    resourceServerIdentifier is api://api.xxxxx.com, and scope is read:file.

    The final result is api://api.xxxxx.com|read:file.

    To obtain all scopes already authorized for the current client, use {resourceServerIdentifier}|.all

    api://api.xxxxx.com|read:file

  4. Request example:

    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'
  5. Response example:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2se******BkxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

Authentication method: OIDC federated authentication

  1. Request method: POST

  2. Header parameters:

    Parameter

    Type

    Description

    Example

    Content-Type

    String

    Fixed value: application/x-www-form-urlencoded

    application/x-www-form-urlencoded

  3. Request parameters:

    Parameter

    Type

    Description

    Example

    grant_type

    String

    Fixed value: client_credentials.

    client_credentials

    client_id

    String

    The application ID.

    client_assertion_type

    String

    The client assertion type. Fixed value: urn:cloud:idaas:params:oauth:client-assertion-type:id-token-bearer.

    client_assertion

    String

    The OIDC token used by the client, in JWT format.

    scope

    String

    You can request permissions by scope. String values are joined with spaces. The format is resourceServerIdentifier+"|"+scope. For example:

    resourceServerIdentifier is api://api.xxxxx.com, and scope is read:file.

    The final result is api://api.xxxxx.com|read:file.

    To obtain all scopes already authorized for the current client, use {resourceServerIdentifier}|.all

    api://api.xxxxx.com|read:file

    application_federated_credential_name

    String

    The name of the application's federated credential.

    aliyun_ack

  4. Request example:

    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'
  5. Response parameters:

    Parameter

    Type

    Nullable

    Description

    access_token

    String

    No

    The access token value.

    expires_in

    Long

    No

    The validity period, as a UNIX timestamp, in seconds.

    expires_at

    Long

    No

    The expiration time, as a UNIX timestamp, in seconds.

    token_type

    String

    No

    The access token type.

  6. Response example:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2se******NHBkxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

Authentication method: PKCS#7 signature authentication

  1. Request method: POST

  2. Header parameters:

    Parameter

    Type

    Description

    Example

    Content-Type

    String

    Fixed value: application/x-www-form-urlencoded

    application/x-www-form-urlencoded

  3. Request parameters:

    Parameter

    Type

    Description

    Example

    grant_type

    String

    Fixed value: client_credentials.

    client_credentials

    client_id

    String

    The application ID.

    client_assertion_type

    String

    The client assertion type. Fixed value: urn:cloud:idaas:params:oauth:client-assertion-type:pkcs7-bearer.

    client_assertion

    String

    The PKCS#7 signature value.

    scope

    String

    You can request permissions by scope. String values are joined with spaces. The format is resourceServerIdentifier+"|"+scope. For example:

    resourceServerIdentifier is api://api.xxxxx.com, and scope is read:file.

    The final result is api://api.xxxxx.com|read:file.

    To obtain all scopes already authorized for the current client, use {resourceServerIdentifier}|.all

    api://api.xxxxx.com|read:file

    application_federated_credential_name

    String

    The name of the application's federated credential.

    aliyun_ecs

  4. Request example:

    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'
  5. Response parameters:

    Parameter

    Type

    Nullable

    Description

    access_token

    String

    No

    The access token value.

    expires_in

    Long

    No

    The validity period, as a UNIX timestamp, in seconds.

    expires_at

    Long

    No

    The expiration time, as a UNIX timestamp, in seconds.

    token_type

    String

    No

    The access token type.

  6. Response example:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2sep******HBkxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

Authentication method: PrivateCA certificate authentication

  1. Request method: POST

  2. Header parameters:

    Parameter

    Type

    Description

    Example

    Content-Type

    String

    Fixed value: application/x-www-form-urlencoded.

    application/x-www-form-urlencoded

  3. Request parameters:

    Parameter

    Type

    Description

    Example

    grant_type

    String

    Fixed value: client_credentials.

    client_credentials

    client_id

    String

    The application ID.

    client_assertion_type

    String

    The client assertion type. Fixed value: urn:cloud:idaas:params:oauth:client-assertion-type:x509-jwt-bearer.

    client_assertion

    String

    The JWT token issued by the client using private_key.

    scope

    String

    You can request permissions by scope. String values are joined with spaces. The format is resourceServerIdentifier+"|"+scope. For example:

    resourceServerIdentifier is api://api.xxxxx.com, and scope is read:file.

    The final result is api://api.xxxxx.com|read:file.

    To obtain all scopes already authorized for the current client, use:

    api://api.xxxxx.com|read:file

    client_x509

    String

    The end-entity certificate (leaf certificate), that is, the client certificate.

    base64-encoded Distinguished Encoding Rules

    -----BEGIN CERTIFICATE-----

    xxxxxx

    -----END CERTIFICATE-----

    client_x509_chain

    String

    The list of intermediate certificates, Intermediate CA.

    base64-encoded Distinguished Encoding Rules

    Join multiple certificates with line breaks. Each certificate must be in the following format:

    -----BEGIN CERTIFICATE----- at the beginning
    -----END CERTIFICATE----- at the end

    -----BEGIN CERTIFICATE-----

    xxxxxx1

    -----END CERTIFICATE-----

    -----BEGIN CERTIFICATE-----

    xxxxxx1

    -----END CERTIFICATE-----

    application_federated_credential_name

    String

    The name of the application's federated credential.

    private_ca

  4. Request example:

    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'
  5. Response parameters:

    Parameter

    Type

    Nullable

    Description

    access_token

    String

    No

    The access token value.

    expires_in

    Long

    No

    The validity period, as a UNIX timestamp, in seconds.

    expires_at

    Long

    No

    The expiration time, as a UNIX timestamp, in seconds.

    token_type

    String

    No

    The access token type.

  6. Response example:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2******HBkxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

Error codes

HttpCode

error

Error message

Description

400

invalid_request

Require parameter variable: grant_type

The request is missing a required parameter, contains an invalid parameter value, contains multiple parameters, or is malformed.

400

authentication_required

Authentication required, allowed authentication methods: [client_secret_basic, client_secret_post, client_secret_jwt, private_key_jwt]

The authentication method is incorrect. Supported authentication methods:

client_secret_basic, client_secret_post, client_secret_jwt,

private_key_jwt.

400

invalid_client_credential

Invalid client_assertion, reasons(s): [expired]

The client_assertion is invalid. The token has expired.

400

invalid_grant

Invalid or not supported grant_type: authorization_code

The grant_type is not supported.

400

invalid_scope

Invalid scope: http://www.example.com|read:file

The requested scope is invalid, unknown, or malformed.

500

internal_error

Unexpected internal error

An internal server error occurred.

Appendix 1: Generate a JWT signature using Java (RS256 algorithm)

This appendix provides a complete example of generating a JWT (JSON Web Token) signature in Java, using the RS256 asymmetric encryption algorithm. It includes:

  1. Maven dependency configuration:

    <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>
  2. Java code example:

    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;
    
    public class JwtGenerator {
        private static final String PRIVATE_KEY = "your-private-key"; // Replace with your key
    
        // Enter the application's client_id
        private static final String ISSUER = "your_client_id";
    
        // Enter the application's client_id
        private static final String SUBJECT = "your_client_id";
    
        // Enter the token endpoint of the application
        private static final String AUDIENCE = "your_token_endpoint";
    
        public static void main(String[] args) throws Exception {
            // Key
            Key securityKey = RsaKeyConverter.getPrivateKeyFromString(PRIVATE_KEY);
    
            Map<String, Object> claims = new HashMap<>();
            claims.put("jti", UUID.randomUUID().toString()); // Anti-replay jti
    
            // Set the expiration time. It cannot exceed 30 minutes.
            long expirationTime = 1000 * 60 * 30;
            Date expirationDate = new Date(System.currentTimeMillis() + expirationTime);
    
            // Generate 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 token:");
            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;
    
    public class RsaKeyConverter {
    
        public static PrivateKey getPrivateKeyFromString(String privateKeyStr) throws Exception {
            // Remove the PEM header and footer
            String privateKeyPEM = privateKeyStr
                    .replace("-----BEGIN PRIVATE KEY-----", "")
                    .replace("-----END PRIVATE KEY-----", "")
                    .replaceAll("\\s+", "");  // Remove all whitespace characters
    
            // Base64 decode
            byte[] encoded = Base64.getDecoder().decode(privateKeyPEM);
    
            // Generate the private key using PKCS8EncodedKeySpec
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return keyFactory.generatePrivate(keySpec);
        }
    
        public static PublicKey getPublicKeyFromString(String publicKeyStr) throws Exception {
            // Remove the PEM header and footer
            String publicKeyPEM = publicKeyStr
                    .replace("-----BEGIN PUBLIC KEY-----", "")
                    .replace("-----END PUBLIC KEY-----", "")
                    .replaceAll("\\s+", "");  // Remove all whitespace characters
    
            // Base64 decode
            byte[] encoded = Base64.getDecoder().decode(publicKeyPEM);
    
            // Generate the public key using X509EncodedKeySpec
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return keyFactory.generatePublic(keySpec);
        }
    }

Appendix 2: Generate a JWT signature using Java (HS256 algorithm)

This appendix provides a complete example of generating a JWT (JSON Web Token) signature in Java, using the HS256 signature algorithm. The example includes:

  1. Maven dependency configuration:

    <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>
  2. Java code example:

    public class JwtGenerator {
    
        private static final String SECRET_KEY = "your_secret_key"; // Replace with your key
    
        // Enter the application's client_id
        private static final String ISSUER = "your_client_id";
    
        // Enter the application's client_id
        private static final String SUBJECT = "your_client_id";
    
        // Enter the token endpoint of the application
        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()); // Anti-replay jti
    
            // Set the expiration time. It cannot exceed 30 minutes.
            long expirationTime = 1000 * 60 * 30;
            Date expirationDate = new Date(System.currentTimeMillis() + expirationTime);
    
            // Generate 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{
            // Generate JWT
            String jwt = generateJwt();
            System.out.println("Generated JWT: " + jwt);
        }
    }