Skip to content

Commit

Permalink
Merge pull request #58 from AlibabaCloudLandingZone/solution-fc-sts-t…
Browse files Browse the repository at this point in the history
…oken/0.0.1

solution-fc-sts-token/0.0.1
  • Loading branch information
wibud authored Jun 19, 2024
2 parents 068609e + de507f2 commit 7fed5b1
Show file tree
Hide file tree
Showing 10 changed files with 401 additions and 0 deletions.
32 changes: 32 additions & 0 deletions solution/solution-fc-sts-token/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

### IntelliJ IDEA ###
.idea/

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
64 changes: 64 additions & 0 deletions solution/solution-fc-sts-token/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# 通过FC函数角色实现临时凭证的获取和使用
通过FC函数角色和RAM角色关联,使用STS Token访问云资源,避免了将访问密钥硬编码在代码中,从而消除AK泄露的风险。临时凭证(STS Token)的使用有效解决了永久凭证(AK/SK)可能带来的安全风险问题。
本方案提供Java/Python代码示例,客户能够快速完成应用改造,减少开发和部署的复杂度。

## 使用步骤
### 目录结构说明
```
solution-fc-sts-token/
└── code-example/
├── java/ # java示例代码
├── python/ # python示例代码
└── nodejs/ # Node.js示例代码
```
### Java示例代码
```
java/
└── src/main/java/
│ └── org/
│ └── example/
│ ├── aliyun_sdk/ # 阿里云SDK配置FC函数角色凭证示例
│ ├── oss_sdk/ # OSS SDK配置FC函数角色凭证示例
│ └── sls_sdk/ # SLS SDK配置FC函数角色凭证示例
└── pom.xml # Maven项目的配置文件
```
#### 如何运行
该示例代码需要在FC函数中执行,请确保选择Java作为FC函数的运行环境。

请您选择您的SDK类型对应的示例代码,将其打包成jar文件后上传至函数计算以运行。
请确保运行环境中已配置好Java和Maven。
1. Java Development Kit (JDK):确保已安装Java 8或更高版本。
2. Apache Maven:确保已安装Maven 3.6.0或更高版本。

首先进入Java代码目录:
```bash
cd code-example/java
```
复制maven依赖:
```bash
mvn dependency:copy-dependencies
```
编译代码:
```bash
mkdir target/classes
javac -d target/classes -cp "target/dependency/*" src/main/java/org/example/<PathName>/<ClassName>.java
```
打包代码:
```bash
jar cvf target/<JarFileName>.jar -C target/classes . -C target/dependency .
```

注意:
请确认函数中 配置 > 运行时 > 请求处理程序 的格式为 [package].[class]::[method]。例如,当前值为 org.example.aliyun_sdk.App::handleRequest,那么在函数被触发时,将执行 org.example.aliyun_sdk 包中 App 类中的 handleRequest 函数。

### Python示例代码
```
python/
├── aliyun_sdk/ # 阿里云SDK配置FC函数角色凭证示例
├── oss_sdk/ # OSS SDK配置FC函数角色凭证示例
└── sls_sdk/ # SLS SDK配置FC函数角色凭证示例
```
#### 如何运行
该示例代码需要在FC函数中执行,请确保选择Python作为FC函数的运行环境。

请您选择您的SDK类型对应的示例代码,复制代码后上传至函数计算运行即可。
74 changes: 74 additions & 0 deletions solution/solution-fc-sts-token/code-example/java/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<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>

<groupId>org.example</groupId>
<artifactId>solution-fc-sts-token</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>solution-fc-sts-token</name>
<url>http://maven.apache.org</url>

<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>
<!--2.0 vpc-sdk-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>vpc20160428</artifactId>
<version>7.8.7</version>
</dependency>
<!--1.0 vpc-sdk-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-vpc</artifactId>
<version>3.2.28</version>
</dependency>
<!--oss-sdk-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.17.2</version>
</dependency>
<!--sls-sdk-->
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>aliyun-log</artifactId>
<version>0.6.107</version>
</dependency>

<!--fc-sdk -->
<dependency>
<groupId>com.aliyun.fc.runtime</groupId>
<artifactId>fc-java-core</artifactId>
<version>1.4.1</version>
</dependency>

<dependency>
<groupId>com.aliyun.fc.runtime</groupId>
<artifactId>fc-java-event</artifactId>
<version>1.2.0</version>
</dependency>

<!--建议使用最新发布的Credentials版本。-->
<!--请查看ChangeLog.txt获取所有已发布的版本列表。-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>credentials-java</artifactId>
<version>0.3.1</version>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68.noneautotype</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.example.aliyun_sdk;

import java.io.InputStream;
import java.io.OutputStream;

import com.alibaba.fastjson.JSON;
import com.aliyun.credentials.utils.AuthConstant;
import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.Credentials;
import com.aliyun.fc.runtime.StreamRequestHandler;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.vpc20160428.Client;
import com.aliyun.vpc20160428.models.DescribeVpcsRequest;
import com.aliyun.vpc20160428.models.DescribeVpcsResponse;

public class App implements StreamRequestHandler {

@Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) {
// 从上下文获取凭证信息
Credentials creds = context.getExecutionCredentials();

try {
Config config = new Config().setRegionId("cn-hangzhou").setCredential(createCredential(creds));

// 调用OpenAPI实现业务功能
Client vpcClient = new Client(config);
DescribeVpcsRequest describeVpcsRequest = new DescribeVpcsRequest().setRegionId("cn-hangzhou");
DescribeVpcsResponse describeVpcsResponse = vpcClient.describeVpcs(describeVpcsRequest);
outputStream.write(JSON.toJSONString(describeVpcsResponse).getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}

private static com.aliyun.credentials.Client createCredential(Credentials creds) {
com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config();

config.type = AuthConstant.STS;
config.accessKeyId = creds.getAccessKeyId();
config.accessKeySecret = creds.getAccessKeySecret();
config.securityToken = creds.getSecurityToken();

return new com.aliyun.credentials.Client(config);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.example.oss_sdk;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.StreamRequestHandler;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.auth.Credentials;
import com.aliyun.oss.common.auth.DefaultCredentials;
import com.aliyun.oss.model.Bucket;

public class App implements StreamRequestHandler {

@Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
// 从上下文获取凭证信息
com.aliyun.fc.runtime.Credentials creds = context.getExecutionCredentials();

// 转化为OSS的Credentials
Credentials ossCreds = new DefaultCredentials(creds.getAccessKeyId(), creds.getAccessKeySecret(), creds.getSecurityToken());

CredentialsProvider credentialsProvider = new DefaultCredentialProvider(ossCreds);

// OSS endpoint,以杭州为例
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";

OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

// 调用OpenAPI
List<Bucket> buckets = ossClient.listBuckets();
outputStream.write(JSON.toJSONString(buckets).getBytes());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.example.sls_sdk;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.StreamRequestHandler;
import com.aliyun.openservices.log.Client;
import com.aliyun.openservices.log.ClientBuilder;
import com.aliyun.openservices.log.common.Project;
import com.aliyun.openservices.log.common.auth.Credentials;
import com.aliyun.openservices.log.common.auth.CredentialsProvider;
import com.aliyun.openservices.log.common.auth.DefaultCredentials;
import com.aliyun.openservices.log.common.auth.StaticCredentialsProvider;
import com.aliyun.openservices.log.exception.LogException;

public class App implements StreamRequestHandler {

@Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
// 从上下文获取凭证信息
com.aliyun.fc.runtime.Credentials creds = context.getExecutionCredentials();

// 转化为SLS的Credentials
Credentials slsCreds = new DefaultCredentials(creds.getAccessKeyId(), creds.getAccessKeySecret(), creds.getSecurityToken());

CredentialsProvider credentialsProvider = new StaticCredentialsProvider(slsCreds);

// SLS endpoint,以杭州为例
String endpoint = "https://cn-hangzhou.log.aliyuncs.com";

Client slsClient = new ClientBuilder(endpoint, credentialsProvider).build();

// 调用OpenAPI
try {
List<Project> projects = slsClient.ListProject().getProjects();
outputStream.write(JSON.toJSONString(projects).getBytes());
} catch (LogException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict';

const RPCClient = require('@alicloud/pop-core').RPCClient;
const httpModule = require('https');

const keepAliveAgent = new httpModule.Agent({
keepAlive: false,
});
const requestOption = {
method: 'POST',
formatParams: false,
timeout: 10000,
agent: keepAliveAgent,
};

exports.handler = (event, context, callback) => {
main(context)
.then((res) => {
callback(null, JSON.stringify(res));
})
.catch((err) => callback(err));
};

async function main(context) {
const { credentials, logger } = context;

// 从上下文中获取 AK/SK/Security Token,初始化请求 OpenAPI 的 Client
const client = new RPCClient({
accessKeyId: credentials.accessKeyId,
accessKeySecret: credentials.accessKeySecret,
securityToken: credentials.securityToken,
endpoint: 'https://vpc.cn-hangzhou.aliyuncs.com',
apiVersion: '2016-04-28'
});

const vpcList = await client.request('DescribeVpcs', {
pageSize: 1
}, requestOption);
return vpcList;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from aliyunsdkvpc.request.v20160428 import DescribeVpcsRequest
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.auth.credentials import StsTokenCredential

def handler(event, context):
# 从上下文获取凭证信息
creds = context.credentials

# 创建凭证对象
credentials = StsTokenCredential(creds.access_key_id, creds.access_key_secret, creds.security_token)

# 初始化客户端,设置地区等信息
client = AcsClient(region_id='cn-hangzhou', credential=credentials)

# 创建请求对象
request = DescribeVpcsRequest.DescribeVpcsRequest()

# 设置参数,例如可以设置过滤条件等,这里只展示最基本的调用
request.set_accept_format('json')

# 发起请求并获取响应
response = client.do_action_with_exception(request)

# 打印响应结果
return(str(response, encoding='utf-8'))
Loading

0 comments on commit 7fed5b1

Please sign in to comment.