關於阿里雲oss物件儲存含sts授權詳解,java程式碼
我在專案上需要使用一個阿里雲的oss來進行圖片的上傳。看過oss的介紹和api之後,先寫一個簡單的程式碼。
maven地址引入jar
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>.
public void uploadImage(String fileName, InputStream inputStream) throws IOException { // 建立OSSClient例項。 OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret); // 建立上傳Object的Metadata ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentLength(inputStream.available()); objectMetadata.setCacheControl("no-cache"); objectMetadata.setHeader("Pragma", "no-cache"); objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf(".")))); objectMetadata.setContentDisposition("inline;filename=" + fileName); ossClient.putObject(bucketName, fileName, inputStream, objectMetadata); // 關閉OSSClient。 ossClient.shutdown(); }
endpoint是你建立的oss伺服器的地址。比如 oss-cn-shenzhen.aliyuncs.com
accessKeyId 是你使用者的key accessKeySecret是你使用者的密碼
bucketName 你建立的儲存空間
通過ossClient.putObject()即可上傳。
那麼下載呢。也是通過ossClient
// 設定URL過期時間 Date expiration = new Date(new Date().getTime() + 36000 * 1000 * 24 * 365 * 10); // 生成原圖URL URL url = ossClient.generatePresignedUrl(bucketName, fileName, expiration); // 請求處理樣式後的url String style = "image/resize,p_50"; GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, fileName, HttpMethod.GET); req.setExpiration(expiration); req.setProcess(style); URL signedUrl = ossClient.generatePresignedUrl(req);
第一個url是我們獲取原圖的地址,該地址直接放在瀏覽器就可以看到啦~
第二個signedUrl是oss自帶的圖片處理功能,返回的一個url,如何處理呢,這裡按照oss規定的格式設定,即可進行對應的處理。比如我這裡resize,p_50就是縮小50%。
參考文件:https://help.aliyun.com/document_detail/47505.html?spm=a2c4g.11186623.6.715.pb7e6d
這樣簡單的上傳下載就完成了。
但是給安全檢測,發現一個安全大漏洞。。。在url中包含你的accessKeyId,這是非常不安全的。。。。於是阿里肯定會對安全你做處理的。。。
那麼接下來,我就說一下,阿里這邊的安全處理。
sts:我們仍然會使用一個帶有accessKeyId的url,只不過這個url是以sts開頭的一個臨時授權的accessKeyId
接下來,就教大家如何去設定。
首先開通RAM,並建立一個RAM使用者
ram使用者代表什麼呢,就相當於你的一個映象,你可以給他分配許可權。這裡你需要給他分配,允許分配臨時授權accessKeyId的許可權sts。
這個RAM使用者接下來就是你的接線員了。。程式程式碼中用的accessKeyId和密碼就是該使用者的。
之後新建一個角色
這個角色,它有什麼許可權,那麼你分配的臨時授權accessKeyId和密碼和token就有什麼許可權。。
看程式碼。
public static final String REGION_CN_HANGZHOU = "cn-hangzhou";
private Map<String, String> stsService() throws ClientException {
// 只有 RAM使用者(子賬號)才能呼叫 AssumeRole 介面 .
// 阿里雲主賬號的AccessKeys不能用於發起AssumeRole請求
// 首先在RAM控制檯建立一個RAM使用者,併為這個使用者建立AccessKeys
// 扮演角色的時候額外加上的一個許可權限制,寫法和授權策略一樣
String policy = null;
// 可以為空 是一個用來標示臨時憑證的名稱,一般來說建議使用不同的應用程式使用者來區分
String roleSessionName = "roleUser";
// 臨時憑證的有效期,單位是s,最小為900,最大為3600
long sessionTime = 900;
DefaultProfile.addEndpoint("", "", "Sts", endpoint);
IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, accessKeyId, accessKeySecret);
// 用profile構造client
DefaultAcsClient client = new DefaultAcsClient(profile);
final AssumeRoleRequest request = new AssumeRoleRequest();
request.setMethod(MethodType.POST);
// 臨時Token的會話名稱,自己指定用於標識你的使用者,主要用於區分Token頒發給誰
// acs:ram::$accountID:role/$roleName
request.setRoleArn(roleArn);
request.setRoleSessionName(roleSessionName);
request.setPolicy(policy);
request.setDurationSeconds(sessionTime);
// 發起請求,並得到response
final AssumeRoleResponse response = client.getAcsResponse(request);
System.out.println("Expiration: " + response.getCredentials().getExpiration());
System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());
System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
System.out.println("Security Token: " + response.getCredentials().getSecurityToken());
System.out.println("RequestId: " + response.getRequestId());
Map<String, String> result = new HashMap<String, String>();
result.put("accessKeyId", response.getCredentials().getAccessKeyId());
result.put("accessKeySecret", response.getCredentials().getAccessKeySecret());
result.put("tokenSecret", response.getCredentials().getSecurityToken());
return result;
}
這裡有一個屬性、、roleArn,他呢就是證明是哪個角色的。在角色管理中查詢。
這裡依然通過ossClient來回去url,不過是通過上面獲得的key,密碼和token
// 建立OSSClient例項。
OSSClient ossClient = new OSSClient(endpoint, stsService.get("accessKeyId"), stsService.get("accessKeySecret"),
stsService.get("tokenSecret"));