Skip to content

Commit

Permalink
Merge pull request #73 from AlibabaCloudLandingZone/solution-cross-ac…
Browse files Browse the repository at this point in the history
…count-sts-token/0.0.2

solution-cross-account-sts-token/0.0.2
  • Loading branch information
wibud authored Aug 14, 2024
2 parents a06e366 + 4ead173 commit 3d7edfb
Show file tree
Hide file tree
Showing 15 changed files with 515 additions and 6 deletions.
16 changes: 10 additions & 6 deletions solution/solution-cross-account-sts-token/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,16 @@

```
.
└── common
└── src/main/java
└── org
└── example
├── sdk1_0 // 1.0版本SDK简单示例
└── sdk2_0 // 2.0版本SDK简单示例
├── common
│ └── src/main/java
│ └── org
│ └── example
│ ├── sdk1_0 // 1.0版本SDK简单示例
│ └── sdk2_0 // 2.0版本SDK简单示例
└── spring-boot
└── assume-role
├── sdk-v1 // 1.0版本SDK SpringBoot示例
└── sdk-v2 // 2.0版本SDK SpringBoot示例
```

执行前,请确保运行环境中已配置好Java和Maven。
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
<groupId>org.example</groupId>
<artifactId>sdk-v1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
<exec.cleanupDaemonThreads>false</exec.cleanupDaemonThreads>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.51</version>
</dependency>

<!--1.0 sdk core-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.7.1</version>
</dependency>

<!--跨账号业务操作所需sdk-->
<!--请根据您实际的业务操作所需选择对应的sdk-->
<!--本示例中以调用GetCallerIdentity获取当前调用者身份信息为例-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-sts</artifactId>
<version>3.1.2</version>
</dependency>

<!-- Requires: version >= 0.3.4 -->
<!-- 推荐使用最新版本 -->
<!--获取所有已发布的版本列表,请参见https://github.com/aliyun/credentials-java/blob/master/ChangeLog.txt-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>credentials-java</artifactId>
<version>0.3.5</version>
</dependency>

<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea</artifactId>
<version>1.3.0</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.example.config;

import com.aliyun.credentials.Client;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CredentialConfig {

// 初始化凭据客户端,Credential SDK Client 应该是单例,不要每次请求都重新 new 一个,避免内存泄露
// 使用Credentials工具,保证您的应用程序本身是无AK的
// 借助Credentials工具的默认凭据链,您可以用同一套代码,通过程序之外的配置来控制不同环境下的凭据获取方式
// 当您在初始化凭据客户端不传入任何参数时,Credentials工具将会尝试按照如下顺序查找相关凭据信息(优先级由高到低):
// 1. 使用系统属性
// 2. 使用环境变量
// 3. 使用OIDC RAM角色
// 4. 使用配置文件
// 5. 使用ECS实例RAM角色(需要通过环境变量 ALIBABA_CLOUD_ECS_METADATA 指定 ECS 实例角色名称;通过环境变量 ALIBABA_CLOUD_ECS_IMDSV2_ENABLE=true 开启在加固模式下获取STS Token)
// 详情请参考:https://help.aliyun.com/zh/sdk/developer-reference/v2-manage-access-credentials#3ca299f04bw3c
// 要使用默认凭据链,初始化 Client 时,必须使用空的构造函数,不能配置 Config 入参
// 除了使用默认凭据链,您也可以在代码中显式配置,来初始化凭据客户端
// 详情请参考:https://help.aliyun.com/zh/sdk/developer-reference/v2-manage-access-credentials#a9e9aa404bzfy
@Bean(name = "credentialClient")
Client getCredentialClient() {
return new Client();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.example.config;

import com.aliyun.credentials.models.CredentialModel;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.BasicSessionCredentials;
import com.aliyuncs.auth.STSAssumeRoleSessionCredentialsProvider;
import com.aliyuncs.profile.DefaultProfile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CrossAccountSdkClientConfig {

@Value("${region.id}")
String regionId;

@Value("${role.arn}")
String roleArn;

@Autowired
com.aliyun.credentials.Client credentialClient;

/**
* 使用跨账号的角色身份,初始化SDK 1.0客户端Client,作为单例使用
* 如果您有多个账号都需要跨账号操作,需要为每个账号创建一个Client
*/
@Bean(name = "crossAccountSdkClient")
com.aliyuncs.IAcsClient getCrossAccountSdkClient() {
DefaultProfile profile = DefaultProfile.getProfile(regionId);
// 用凭据客户端初始化角色扮演的CredentialsProvider:STSAssumeRoleSessionCredentialsProvider,实现跨账号角色扮演
// 该CredentialsProvider支持自动刷新STS Token
STSAssumeRoleSessionCredentialsProvider provider = new STSAssumeRoleSessionCredentialsProvider(
() -> {
// 保证线程安全,从 CredentialModel 中获取 ak/sk/security token
CredentialModel credentialModel = credentialClient.getCredential();
String ak = credentialModel.getAccessKeyId();
String sk = credentialModel.getAccessKeySecret();
String token = credentialModel.getSecurityToken();
return new BasicSessionCredentials(ak, sk, token);
},
roleArn,
profile
)
// 角色会话名称
.withRoleSessionName("WellArchitectedSolutionDemo")
// STS Token 有效期,单位:秒
.withRoleSessionDurationSeconds(3600L);

// 初始化SDK 1.0客户端
return new DefaultAcsClient(profile, provider);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.example.controller;

import com.alibaba.fastjson2.JSON;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.sts.model.v20150401.GetCallerIdentityRequest;
import com.aliyuncs.sts.model.v20150401.GetCallerIdentityResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Controller {

@Autowired
com.aliyuncs.IAcsClient crossAccountSdkClient;

/**
* 调用API,跨账号进行资源操作
* 以调用GetCallerIdentity获取当前调用者身份信息为例
*/
@GetMapping("/getCallerIdentity")
public String getCallerIdentity() {
GetCallerIdentityRequest getCallerIdentityRequest = new GetCallerIdentityRequest();
try {
GetCallerIdentityResponse getCallerIdentityResponse = crossAccountSdkClient.getAcsResponse(getCallerIdentityRequest);
return JSON.toJSONString(getCallerIdentityResponse);
} catch (ClientException e) {
e.printStackTrace();
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
server.port = 7001

# 地域,以杭州地域为例
region.id=cn-hangzhou

# 您实际要扮演的RAM角色ARN
# 格式为 acs:ram::${账号ID}:role/${角色名称}
role.arn=acs:ram::<account-id>:role/<role-name>
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
<groupId>org.example</groupId>
<artifactId>sdk-v2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
<exec.cleanupDaemonThreads>false</exec.cleanupDaemonThreads>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.9.3</version>
</dependency>

<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.51</version>
</dependency>

<!--2.0 sdk-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>sts20150401</artifactId>
<version>1.1.4</version>
</dependency>

<!-- Requires: version >= 0.3.4 -->
<!-- 推荐使用最新版本 -->
<!--获取所有已发布的版本列表,请参见https://github.com/aliyun/credentials-java/blob/master/ChangeLog.txt-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>credentials-java</artifactId>
<version>0.3.5</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@EnableCaching
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.example.config;

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.TimeUnit;

@Configuration
public class CacheConfig {

/**
* 示例中使用简单的本地缓存,请更换为您真实使用的持久化缓存
* 缓存项的缓存时间一定要小于STS Token有效期,避免缓存时间过长而STS Token过期导致程序错误
* 示例中,缓存时间为STS Token的有效期(60min)-5min
*/
@Bean
public CacheManager cacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
cacheManager.setCaffeine(
Caffeine.newBuilder()
.maximumSize(100)
.expireAfterWrite(3300, TimeUnit.SECONDS)
);
return cacheManager;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.example.config;

import com.aliyun.credentials.Client;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CredentialConfig {

// 初始化凭据客户端,Credential SDK Client 应该是单例,不要每次请求都重新 new 一个,避免内存泄露
// 使用Credentials工具,保证您的应用程序本身是无AK的
// 借助Credentials工具的默认凭据链,您可以用同一套代码,通过程序之外的配置来控制不同环境下的凭据获取方式
// 当您在初始化凭据客户端不传入任何参数时,Credentials工具将会尝试按照如下顺序查找相关凭据信息(优先级由高到低):
// 1. 使用系统属性
// 2. 使用环境变量
// 3. 使用OIDC RAM角色
// 4. 使用配置文件
// 5. 使用ECS实例RAM角色(需要通过环境变量 ALIBABA_CLOUD_ECS_METADATA 指定 ECS 实例角色名称;通过环境变量 ALIBABA_CLOUD_ECS_IMDSV2_ENABLE=true 开启在加固模式下获取STS Token)
// 详情请参考:https://help.aliyun.com/zh/sdk/developer-reference/v2-manage-access-credentials#3ca299f04bw3c
// 要使用默认凭据链,初始化 Client 时,必须使用空的构造函数,不能配置 Config 入参
// 除了使用默认凭据链,您也可以在代码中显式配置,来初始化凭据客户端
// 详情请参考:https://help.aliyun.com/zh/sdk/developer-reference/v2-manage-access-credentials#a9e9aa404bzfy
@Bean(name = "credentialClient")
Client getCredentialClient() {
return new Client();
}
}
Loading

0 comments on commit 3d7edfb

Please sign in to comment.