M2M Client Token调用示例

本文档提供阿里云IDaaS(EIAM)中M2M客户端令牌调用示例,详细说明如何通过OAuth 2.0客户端模式获取访问令牌,并调用API实现系统间安全认证。

调用示例

认证方式:client_secret_basic

  1. 请求方法:POST

  2. header头参数:

    参数名

    类型

    说明

    示例

    Authorization

    String

    Basic Base64(clientId:clientSecret)

    通过base64编码的clientIdClientSecret

    YXBwX201ZG9vemVzbm81Mmtxxxxxxxxx

    Content-Type

    String

    固定值:application/x-www-form-urlencoded

    application/x-www-form-urlencoded

  3. 请求参数:

    参数名

    类型

    说明

    示例

    grant_type

    String

    固定值:client_credentials。

    client_credentials

    scope

    String

    可以根据scope来进行权限申请,String类型空格拼接。格式为:resourceServerIdentifier+"|"+scope,如:

    resourceServerIdentifier是:api://api.xxxxx.com,scope是:read:file

    最终返回结果为:api://api.xxxxx.com|read:file

    获取当前client已经授权的所有scopes,使用:{resourceServerIdentifier}|.all

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

    client_id

    string

    应用ID。

  4. 请求示例:

    curl --location --request POST 'https://XXXX.aliyunidaas.com/api/v2/iauths_system/oauth2/token' 
         --header 'Authorization:xxxxxxx'
         --header 'Content-Type: application/x-www-form-urlencoded' 
         --data-urlencode 'grant_type=client_credentials'
         --data-urlencode 'api://api.xxxxx.com|read:file'
  5. 返回参数:

    参数名

    类型

    是否可为空

    描述

    access_token

    String

    token值。

    expires_in

    Long

    到期时长,单位秒。

    expires_at

    Long

    到期时间,unix时间戳,单位秒。

    token_type

    String

    token类型。

  6. 返回示例:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2sepE4TT9j45xFgRGhEDyS3ovfZDF68Ac4aaQ7c4dBpUahD1cYSCFQbsfpM9ysSArv1pTszcGTZEJK11yGA62GKWd4cf33ZVGsgPfLwYDPX2ZRCUpThTaWoxtXCs9zeZzGwxjc5xtasaQMeuE8PuGeHg9SyMzKxJQVv9ubQhoFXjQkoPUotUms4R2M9SBLpWSCaGDf3oiJ5WCuGyMzJdrrdQeLSB7dU9P1iKbjxGWCmwaMLMkUWZBKsAeYi3xjJmpMsuLq3811KAV5bttwi8z8cafuweuNvwdjfZYCYvNbRAt1nB9Bxn9Q99rdpYawU3eH3UvzkvMYoJ5wtnGSsPJ9B7NHBkxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

认证方式:client_secret_post

  1. 请求方法:POST

  2. header头参数:

    参数名

    类型

    说明

    示例

    Content-Type

    String

    固定值:application/x-www-form-urlencoded

    application/x-www-form-urlencoded

  3. 请求参数:

    参数名

    类型

    说明

    示例

    grant_type

    String

    固定值:client_credentials。

    client_credentials

    client_id

    String

    应用id。

    client_secret

    String

    应用密钥。

    scope

    String

    可以根据scope来进行权限申请,String类型空格拼接。格式为:resourceServerIdentifier+"|"+scope,如:

    resourceServerIdentifier是:api://api.xxxxx.com,scope是:read:file

    最终返回结果为:api://api.xxxxx.com|read:file

    获取当前client已经授权的所有scopes,使用:{resourceServerIdentifier}|.all

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

  4. 请求示例:

    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. 返回示例:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2sepE4TT9j45xFgRGhEDyS3ovfZDF68Ac4aaQ7c4dBpUahD1cYSCFQbsfpM9ysSArv1pTszcGTZEJK11yGA62GKWd4cf33ZVGsgPfLwYDPX2ZRCUpThTaWoxtXCs9zeZzGwxjc5xtasaQMeuE8PuGeHg9SyMzKxJQVv9ubQhoFXjQkoPUotUms4R2M9SBLpWSCaGDf3oiJ5WCuGyMzJdrrdQeLSB7dU9P1iKbjxGWCmwaMLMkUWZBKsAeYi3xjJmpMsuLq3811KAV5bttwi8z8cafuweuNvwdjfZYCYvNbRAt1nB9Bxn9Q99rdpYawU3eH3UvzkvMYoJ5wtnGSsPJ9B7NHBkxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

认证方式:client_secret_jwt

  1. 请求方法:POST

  2. header头参数:

    参数名

    类型

    说明

    示例

    Content-Type

    String

    固定值:application/x-www-form-urlencoded

    application/x-www-form-urlencoded

  3. 请求参数:

    参数名

    类型

    说明

    示例

    grant_type

    String

    固定值:client_credentials。

    client_credentials

    client_id

    String

    应用id。

    client_assertion_type

    String

    客户端assertion类型。固定值:urn:ietf:params:oauth:client-assertion-type:jwt-bearer。

    client_assertion

    String

    客户端使用client_secret签发的签名,jwt格式,签名算法使用HS256。请参考:附录二

    scope

    String

    可以根据scope来进行权限申请,String类型空格拼接。格式为:resourceServerIdentifier+"|"+scope,如:

    resourceServerIdentifier是:api://api.xxxxx.com,scope是:read:file

    最终返回结果为:api://api.xxxxx.com|read:file

    获取当前client已经授权的所有scopes,使用:{resourceServerIdentifier}|.all

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

  4. 请求示例:

    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. 返回示例:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2sepE4TT9j45xFgRGhEDyS3ovfZDF68Ac4aaQ7c4dBpUahD1cYSCFQbsfpM9ysSArv1pTszcGTZEJK11yGA62GKWd4cf33ZVGsgPfLwYDPX2ZRCUpThTaWoxtXCs9zeZzGwxjc5xtasaQMeuE8PuGeHg9SyMzKxJQVv9ubQhoFXjQkoPUotUms4R2M9SBLpWSCaGDf3oiJ5WCuGyMzJdrrdQeLSB7dU9P1iKbjxGWCmwaMLMkUWZBKsAeYi3xjJmpMsuLq3811KAV5bttwi8z8cafuweuNvwdjfZYCYvNbRAt1nB9Bxn9Q99rdpYawU3eH3UvzkvMYoJ5wtnGSsPJ9B7NHBkxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

认证方式:private_key_jwt

  1. 请求方法:POST

  2. header头参数:

    参数名

    类型

    说明

    示例

    Content-Type

    String

    固定值:application/x-www-form-urlencoded

    application/x-www-form-urlencoded

  3. 请求参数:

    参数名

    类型

    说明

    示例

    grant_type

    String

    固定值:client_credentials。

    client_credentials

    client_id

    String

    应用id。

    client_assertion_type

    String

    客户端assertion类型。固定值:urn:ietf:params:oauth:client-assertion-type:jwt-bearer。

    client_assertion

    String

    客户端使用私钥签发的签名,jwt格式,签名算法使用RS256。请参考:附录一

    scope

    String

    可以根据scope来进行权限申请,String类型空格拼接。格式为:resourceServerIdentifier+"|"+scope,如:

    resourceServerIdentifier是:api://api.xxxxx.com,scope是:read:file

    最终返回结果为:api://api.xxxxx.com|read:file

    获取当前client已经授权的所有scopes,使用:{resourceServerIdentifier}|.all

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

  4. 请求示例:

    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. 返回示例:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2sepE4TT9j45xFgRGhEDyS3ovfZDF68Ac4aaQ7c4dBpUahD1cYSCFQbsfpM9ysSArv1pTszcGTZEJK11yGA62GKWd4cf33ZVGsgPfLwYDPX2ZRCUpThTaWoxtXCs9zeZzGwxjc5xtasaQMeuE8PuGeHg9SyMzKxJQVv9ubQhoFXjQkoPUotUms4R2M9SBLpWSCaGDf3oiJ5WCuGyMzJdrrdQeLSB7dU9P1iKbjxGWCmwaMLMkUWZBKsAeYi3xjJmpMsuLq3811KAV5bttwi8z8cafuweuNvwdjfZYCYvNbRAt1nB9Bxn9Q99rdpYawU3eH3UvzkvMYoJ5wtnGSsPJ9B7NHBkxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

认证方式:OIDC 联邦认证

  1. 请求方法:POST

  2. header头参数:

    参数名

    类型

    说明

    示例

    Content-Type

    String

    固定值:application/x-www-form-urlencoded

    application/x-www-form-urlencoded

  3. 请求参数:

    参数名

    类型

    说明

    示例

    grant_type

    String

    固定值:client_credentials。

    client_credentials

    client_id

    String

    应用id。

    client_assertion_type

    String

    客户端assertion类型。固定值:urn:cloud:idaas:params:oauth:client-assertion-type:id-token-bearer。

    client_assertion

    String

    客户端使用的OIDC Token,JWT格式。

    scope

    String

    可以根据scope来进行权限申请,String类型空格拼接。格式为:resourceServerIdentifier+"|"+scope,如:

    resourceServerIdentifier是:api://api.xxxxx.com,scope是:read:file

    最终返回结果为:api://api.xxxxx.com|read:file

    获取当前client已经授权的所有scopes,使用:{resourceServerIdentifier}|.all

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

    application_federated_credential_name

    String

    应用联邦凭证名称。

    aliyun_ack

  4. 请求示例:

    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. 返回参数:

    参数名

    类型

    是否可为空

    描述

    access_token

    String

    access token值。

    expires_in

    Long

    到期时长,unix时间戳,单位秒。

    expires_at

    Long

    到期时间,unix时间戳,单位秒。

    token_type

    String

    access token类型。

  6. 返回示例:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2sepE4TT9j45xFgRGhEDyS3ovfZDF68Ac4aaQ7c4dBpUahD1cYSCFQbsfpM9ysSArv1pTszcGTZEJK11yGA62GKWd4cf33ZVGsgPfLwYDPX2ZRCUpThTaWoxtXCs9zeZzGwxjc5xtasaQMeuE8PuGeHg9SyMzKxJQVv9ubQhoFXjQkoPUotUms4R2M9SBLpWSCaGDf3oiJ5WCuGyMzJdrrdQeLSB7dU9P1iKbjxGWCmwaMLMkUWZBKsAeYi3xjJmpMsuLq3811KAV5bttwi8z8cafuweuNvwdjfZYCYvNbRAt1nB9Bxn9Q99rdpYawU3eH3UvzkvMYoJ5wtnGSsPJ9B7NHBkxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

认证方式:PKCS#7 签名认证

  1. 请求方法:POST

  2. header头参数:

    参数名

    类型

    说明

    示例

    Content-Type

    String

    固定值:application/x-www-form-urlencoded

    application/x-www-form-urlencoded

  3. 请求参数:

    参数名

    类型

    说明

    示例

    grant_type

    String

    固定值:client_credentials。

    client_credentials

    client_id

    String

    应用id。

    client_assertion_type

    String

    客户端assertion类型。固定值:urn:cloud:idaas:params:oauth:client-assertion-type:pkcs7-bearer。

    client_assertion

    String

    PKCS#7签名值。

    scope

    String

    可以根据scope来进行权限申请,String类型空格拼接。格式为:resourceServerIdentifier+"|"+scope,如:

    resourceServerIdentifier是:api://api.xxxxx.com,scope是:read:file

    最终返回结果为:api://api.xxxxx.com|read:file

    获取当前client已经授权的所有scopes,使用:{resourceServerIdentifier}|.all

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

    application_federated_credential_name

    String

    应用联邦凭证名称。

    aliyun_ecs

  4. 请求示例:

    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. 返回参数:

    参数名

    类型

    是否可为空

    描述

    access_token

    String

    access token值。

    expires_in

    Long

    到期时长,unix时间戳,单位秒。

    expires_at

    Long

    到期时间,unix时间戳,单位秒。

    token_type

    String

    access token类型。

  6. 返回示例:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2sepE4TT9j45xFgRGhEDyS3ovfZDF68Ac4aaQ7c4dBpUahD1cYSCFQbsfpM9ysSArv1pTszcGTZEJK11yGA62GKWd4cf33ZVGsgPfLwYDPX2ZRCUpThTaWoxtXCs9zeZzGwxjc5xtasaQMeuE8PuGeHg9SyMzKxJQVv9ubQhoFXjQkoPUotUms4R2M9SBLpWSCaGDf3oiJ5WCuGyMzJdrrdQeLSB7dU9P1iKbjxGWCmwaMLMkUWZBKsAeYi3xjJmpMsuLq3811KAV5bttwi8z8cafuweuNvwdjfZYCYvNbRAt1nB9Bxn9Q99rdpYawU3eH3UvzkvMYoJ5wtnGSsPJ9B7NHBkxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

认证方式:PrivateCA 证书认证

  1. 请求方法:POST

  2. header头参数:

    参数名

    类型

    说明

    示例

    Content-Type

    String

    固定值:application/x-www-form-urlencoded。

    application/x-www-form-urlencoded

  3. 请求参数:

    参数名

    类型

    说明

    示例

    grant_type

    String

    固定值:client_credentials。

    client_credentials

    client_id

    String

    应用id。

    client_assertion_type

    String

    客户端assertion类型。固定值:urn:cloud:idaas:params:oauth:client-assertion-type:x509-jwt-bearer。

    client_assertion

    String

    客户端使用private_key签发的JWT Token。

    scope

    String

    可以根据scope来进行权限申请,String类型空格拼接。格式为:resourceServerIdentifier+"|"+scope,如:

    resourceServerIdentifier是:api://api.xxxxx.com,scope是:read:file

    最终返回结果为:api://api.xxxxx.com|read:file

    获取当前client已经授权的所有scopes,使用:

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

    client_x509

    String

    终端证书(叶子证书),即Client Certificate。

    base64-encoded Distinguished Encoding Rules

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

    xxxxxx

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

    client_x509_chain

    String

    中间证书列表,Intermediate CA。

    base64-encoded Distinguished Encoding Rules

    多张证书使用换行拼接。每张证书必须为以下格式:

    -----BEGIN CERTIFICATE-----开始
    -----END CERTIFICATE-----结尾

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

    xxxxxx1

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

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

    xxxxxx1

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

    application_federated_credential_name

    String

    应用联邦凭证名称。

    private_ca

  4. 请求示例:

    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. 返回参数:

    参数名

    类型

    是否可为空

    描述

    access_token

    String

    access token值。

    expires_in

    Long

    到期时长,unix时间戳,单位秒。

    expires_at

    Long

    到期时间,unix时间戳,单位秒。

    token_type

    String

    access token类型。

  6. 返回示例:

    {
      "token_type": "Bearer",
      "access_token": "AT8csE2sepE4TT9j45xFgRGhEDyS3ovfZDF68Ac4aaQ7c4dBpUahD1cYSCFQbsfpM9ysSArv1pTszcGTZEJK11yGA62GKWd4cf33ZVGsgPfLwYDPX2ZRCUpThTaWoxtXCs9zeZzGwxjc5xtasaQMeuE8PuGeHg9SyMzKxJQVv9ubQhoFXjQkoPUotUms4R2M9SBLpWSCaGDf3oiJ5WCuGyMzJdrrdQeLSB7dU9P1iKbjxGWCmwaMLMkUWZBKsAeYi3xjJmpMsuLq3811KAV5bttwi8z8cafuweuNvwdjfZYCYvNbRAt1nB9Bxn9Q99rdpYawU3eH3UvzkvMYoJ5wtnGSsPJ9B7NHBkxxHUG",
      "expires_in": 3600,
      "expires_at": 1733710213
    }

错误码

HttpCode

error

错误信息

说明

400

invalid_request

Require parameter variable: grant_type

请求缺少必需参数、包含无效参数值、包含多个参数或格式错误。

400

authentication_required

Authentication required, allowed authentication methods: [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

Invalid client_assertion, reasons(s): [expired]

无效的client_assertion,token到期。

400

invalid_grant

Invalid or not supported grant_type: authorization_code

不支持的grant_type类型。

400

invalid_scope

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

请求的范围无效、未知或格式错误。

500

internal_error

Unexpected internal error

服务器内部错误。

附录一:使用Java生成JWT(RS256算法)签名

本附录提供了使用Java语言生成JWT(JSON Web Token)签名的完整示例,采用RS256非对称加密算法。内容包含:

  1. 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>
  2. 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("生成的 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);
        }
    }

附录二:使用Java生成JWT(HS256算法)签名

本附录提供使用Java语言生成JWT(JSON Web Token)格式签名的完整示例,采用HS256签名算法。示例包含以下内容:

  1. 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>
  2. 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);
        }
    }