调用阿里云OSS签名URL
業(yè)務(wù)場(chǎng)景
由于項(xiàng)目中未來(lái)會(huì)產(chǎn)生大批量的音視頻文件,全部存在服務(wù)器本地將會(huì)占用大量的空間;因此決定使用阿里云對(duì)象存儲(chǔ)服務(wù)(Object Stroage Service, OSS)實(shí)現(xiàn)文件上云;本地只保存最近3個(gè)月的文件,過(guò)期文件將會(huì)被刪除。如果要查看過(guò)期文件,則先從OSS中下載該文件,然后再進(jìn)行其他的常規(guī)操作。
因?yàn)槭堑谝淮问褂肙SS,因此前期做了大量的準(zhǔn)備工作。在申請(qǐng)了公司的OSS賬號(hào)之后,使用常規(guī)的上傳下載會(huì)提示沒(méi)有權(quán)限,因此在獲取OSS連接時(shí),需要加一個(gè)參數(shù)SecurityToken。而在我獲取SecurityToken的時(shí)候,發(fā)現(xiàn)直接使用SDK中的AssumeRole請(qǐng)求是無(wú)法獲取的,這個(gè)原因是因?yàn)殚_(kāi)發(fā)是在內(nèi)網(wǎng)環(huán)境,而OSS的操作只能在外網(wǎng)環(huán)境進(jìn)行訪問(wèn),因此還需要通過(guò)Proxy代理從內(nèi)網(wǎng)通過(guò)代理服務(wù)器訪問(wèn)外網(wǎng)。通過(guò)之前獲取SecurityToken時(shí)的報(bào)錯(cuò)信息知道其訪問(wèn)域名是sts.aliyuncs.com;在官方文檔中找到了公司對(duì)應(yīng)使用的endPoint的STS地址,詳見(jiàn)阿里云STS接入地址。
于是接下來(lái)我需要自己來(lái)拼接訪問(wèn)STS的訪問(wèn)地址,官方也給了使用簽名的文檔,但是感覺(jué)不是很好。所以把自己的摸索歷程記下來(lái)。
實(shí)現(xiàn)代碼
在阿里云官方的簽名機(jī)制文檔中,給出了詳細(xì)的獲取簽名的步驟,以下代碼中有詳細(xì)的說(shuō)明。
private static String DEMO_ARN = "acs:ram::1234567890123:role/firstrole";private static String DEMO_SESSION_NAME = "client";private static String DEMO_ACCESS_KEY_ID = "testid";private static String DEMO_ACCESS_KEY_SECRET = "testsecret";private static String DEMO_UUID = "571f8fb8-506e-11e5-8e12-b8e8563dc8d2";private static String DEMO_ISO8601TIME = "2015-09-01T05:57:34Z";public static void getSecurityToken() throws NoSuchAlgorithmException, IOException, InvalidKeyException {System.out.println("步驟一、1.使用請(qǐng)求參數(shù)構(gòu)造規(guī)范化的請(qǐng)求字符串(Canonicalized Query String)。");//阿里云提供的獲取ISO8601格式時(shí)間的方法String iso8601Time = ParameterHelper.getISO8601Time(new Date());String uuid = getUUID();//按照文檔的說(shuō)明,要先將參數(shù)按照字典順序排序,然后對(duì)參數(shù)進(jìn)行看起來(lái)很復(fù)雜的編碼//但實(shí)際上已經(jīng)提供了現(xiàn)成的方法進(jìn)行編碼:percentEncode//keyList是我自己手動(dòng)進(jìn)行排序的參數(shù)key值的集合,下面的valueList按順序?qū)?yīng)他們的取值List<String> keyList = new ArrayList<>();keyList.add("AccessKeyId");keyList.add("Action");keyList.add("Format");keyList.add("RoleArn");keyList.add("RoleSessionName");keyList.add("SignatureMethod");keyList.add("SignatureNonce");keyList.add("SignatureVersion");keyList.add("Timestamp");keyList.add("Version");List<String> valueList = new ArrayList<>();valueList.add(DEMO_ACCESS_KEY_ID);valueList.add("AssumeRole");valueList.add("JSON");valueList.add(DEMO_ARN);valueList.add(DEMO_SESSION_NAME);valueList.add("HMAC-SHA1");valueList.add(DEMO_UUID);valueList.add("1.0");valueList.add(DEMO_ISO8601TIME);valueList.add("2015-04-01");StringBuilder url = new StringBuilder();//這里對(duì)參數(shù)的key和value進(jìn)行編碼,使用的方法是官方提供的percentEncode方法for(int i = 0; i < keyList.size(); i ++){String key = keyList.get(i);String value = valueList.get(i);if(i > 0){url.append("&");}url.append(percentEncode(key)).append("=").append(percentEncode(value));}//url這個(gè)變量存儲(chǔ)了獲取簽名必須的內(nèi)容。System.out.println("CQS=" + url.toString());System.out.println("");System.out.println("2.將構(gòu)造的規(guī)范化字符串按照下面的規(guī)則構(gòu)造成待簽名的字符串。");//要注意的是,官方文檔中給出的示例URL包含https://sts.aliyuncs.com/?//但實(shí)際上要進(jìn)行stringToSign的只是?之后的內(nèi)容。String stringToSign = "GET&" + percentEncode("/") + "&" + percentEncode(url.toString());System.out.println("待簽名的字符串=" + stringToSign);System.out.println("");System.out.println("步驟二、1.按照RFC2104的定義,計(jì)算待簽名字符串(StringToSign)的HMAC值。");System.out.println("期望值:gNI7b0AyKZHxDgjBGPDgJ1Ce3L4=");//這里調(diào)用官方提供的方法獲取簽名值//我的日志里可以看出這里并沒(méi)有官方文檔中步驟二里的第二個(gè)小步驟//因?yàn)槠鋵?shí)這里算出來(lái)的HMAC值,就已經(jīng)是Signature的值了//我之前就是又對(duì)HMAC值進(jìn)行了Base64編碼,所以生成的地址一直提示簽名不匹配//原因是因?yàn)楣俜降膕ignString方法中已經(jīng)進(jìn)行了Base64編碼HmacSHA1Signer sha1Signer = new HmacSHA1Signer();String ShaHmac2Res = sha1Signer.signString(stringToSign, DEMO_ACCESS_KEY_SECRET + "&");System.out.println("HMAC值2=" + ShaHmac2Res);System.out.println("");System.out.println("3.將得到的簽名值作為Signature參數(shù)添加到請(qǐng)求參數(shù)中。");StringBuilder urlOfSign = new StringBuilder();urlOfSign.append("https://sts.aliyuncs.com/").append("?").append(url).append("&Signature=").append(percentEncode(ShaHmac2Res));System.out.println("HMAC值2的URL=" + urlOfSign.toString());//上面的urlOfSign就是最終有了簽名的訪問(wèn)地址。System.out.println("over");}總結(jié)
以上是生活随笔為你收集整理的调用阿里云OSS签名URL的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 计世网:IT人员秘密思考的十件事情
- 下一篇: 燃气灶电气线路图及原理_燃气报警器电路图