前言
公司项目用阿里云AK发送短信,一直被攻击,导致AK一直要换,很麻烦,这里用官方推荐的TST token(临时token)来发送短信,有效避免我们的AK被攻击。
1、前置任务
(1)创建RAM角色


(2)分配权限
点进详情里面,对角色进行权限分配

给这三个权限: AliyunSTSAssumeRoleAccess、AliyunDysmsFullAccess、AliyunDysmsReadOnlyAccess
第一个时获取临时token的,第二和第三个时发送短信用的。

(3)保存角色数据,后面代码要填

(4)创建RAM用户

注:如果短信发送失败,可以给用户加上角色的那几个权限。
(5)给用户创建AK(accessId和accesskey)

记得保存号AK数据
(6)统计
通过上面的操作,我们获得了一下数据
角色的:角色名称、ARN、AK
2、代码
(1)依赖
XML
<!-- 阿里云短信服务 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.0.0</version>
</dependency>
<!-- 阿里云短信服务 TST -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>ecs20140526</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>sts20150401</artifactId>
<version>1.1.8</version>
</dependency>
<!-- 阿里云短信服务 TST -->
(2) java
java
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
public class STSTokenUtil {
// 使用 RAM 用户的 AK/SK(仅用于获取临时凭证)
private static final String ACCESS_KEY_ID = <你的accessId>;
private static final String ACCESS_KEY_SECRET = <你的accesskey>;
private static final String ROLE_ARN = <你的角色ARN>;
private static final String ROLE_SESSION_NAME = <你的角色名称>;
private static final String REGIONID = "cn-hangzhou";
// 以下为短信模板配置,需要创建模板
private static final String DOMAIN = "dysmsapi.aliyuncs.com";
private static final String VERSION = "";
private static final String ACTION = "";
private static final String TEMPLATECODE = "";
private static final String SIGNNAME = "";
public static AssumeRoleResponse.Credentials getSTSCredentials() throws ClientException {
DefaultProfile profile = DefaultProfile.getProfile(
REGIONID, // 地域ID
ACCESS_KEY_ID,
ACCESS_KEY_SECRET);
IAcsClient client = new DefaultAcsClient(profile);
AssumeRoleRequest request = new AssumeRoleRequest();
request.setRoleArn(ROLE_ARN);
request.setRoleSessionName(ROLE_SESSION_NAME);
request.setDurationSeconds(3600L); // 凭证有效期(秒)
AssumeRoleResponse response = client.getAcsResponse(request);
return response.getCredentials();
}
public static Client createSmsClient() throws Exception {
// 获取 STS 临时凭证
AssumeRoleResponse.Credentials credentials = STSTokenUtil.getSTSCredentials();
// 使用临时凭证配置短信客户端
Config config = new Config()
.setAccessKeyId(credentials.getAccessKeyId())
.setAccessKeySecret(credentials.getAccessKeySecret())
.setSecurityToken(credentials.getSecurityToken())
.setEndpoint("dysmsapi.aliyuncs.com");
return new Client(config);
}
public static boolean sendVerificationCode(String phoneNumber, String code) {
try {
Client client = STSTokenUtil.createSmsClient();
SendSmsRequest request = new SendSmsRequest()
.setPhoneNumbers(phoneNumber)
.setSignName(SIGNNAME)
.setTemplateCode(TEMPLATECODE )
.setTemplateParam("{\"code\":\"" + code + "\"}");
SendSmsResponse response = client.sendSms(request);
System.out.println(response.body);
return "OK".equals(response);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static void main(String[] args) {
STSTokenUtil.sendVerificationCode("18888888888", "123456");
}
}
说明:
a、因为我们获取到的临时token有失效,建议放在rdis里面存起来,下次用就比较方便,不用一直去请求最新的临时token。(以上代码没写!)
b、代码里面涉及到短信模板,这里我就不做过多说明,因为这个项目就是中途接手,模板创建因该不是很难,我也没有弄,所以就不具体说了。
校验:
在短信服务控制台里面可以看到我们测试的短信是否发送成功

大功告成!