根据OSS子账户获取STS的TOKEN

编程入门 行业动态 更新时间:2024-10-26 04:25:23

根据OSS子<a href=https://www.elefans.com/category/jswz/34/1769251.html style=账户获取STS的TOKEN"/>

根据OSS子账户获取STS的TOKEN

前言

目前来说,很多公司都使用者阿里云的资源,对象存储(OSS)就是其中一个我们经常使用的一个资源,在这个使用的过程中,如果我们想要做到一些安全管理(Security Token Service,简称 STS),以及资源的访问控制(Resource Access Management,简称 RAM),这里面也就是官方描述的RAM和STS。

如果你们平台对接很多个合作方,每个合作方又不想从阿里云中重新购买一个新的阿里云的oss,又想实现对每个合作方的资源的一个访问控制,以及权限管理,那么通过这种结合RAM和STS的方式,就非常容易解决这个问题。

阿里云的官方文档并未给出根据子账户的信息如何获取sts的token的例子,获取sts的token的流程有涉及到加签以及urlencode的处理,以及HMAC-SHA1算法的处理,所以这里面有一些坑,由于网上也没有找到详细的例子,官方也没给出例子,直是简单说了这个流程,所以自己倒腾了半天,才整理出来,并拿到生产上使用,下面结合代码说一下这个整体的实现流程。

实现逻辑

下面这个是官方给出的实现说明

根据子账户获取STS的TOKEN

生成sts的toke的工具类


import java.io.UnsupportedEncodingException;
import java.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.UUID;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;import org.apachemons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;/** 
* @ClassName: GenTempOssUtil 
* @Description: 生成临时的oss信息
* @author wenhuixiang
* @date 2018年5月30日 下午4:35:10 
*  
*/
public class GenTempOssUtil {private static final String ENCODING = "UTF-8";private static final String STANDARD_DATE_FORMAT_UTC = "yyyy-MM-dd'T'HH:mm:ss'Z'";private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";  private final static Logger log = LoggerFactory.getLogger(HttpClientUtil.class);public static void main(String[] args)throws Exception {String accessId="你的accessId信息";String secretKey="你的secretKey信息";String arn="你的arn信息";genOssInfo(accessId, secretKey, arn);}/** * @Title: genOssInfo * @Description:  生产临时的 oss 信息* @param @param accessId 子账户的accessId* @param @param secretKey 子账户的secretKey* @param @param arn       对应子账户的权限信息等*/public static String genOssInfo(String accessId,String secretKey,String arn){StringBuilder stringToSign=new StringBuilder();StringBuilder canonicalizedQueryString=new StringBuilder();StringBuilder reqBuilder=new StringBuilder();String resp=null;String uuid=UUID.randomUUID().toString();SimpleDateFormat sdf = new SimpleDateFormat(STANDARD_DATE_FORMAT_UTC);sdf.setTimeZone(TimeZone.getTimeZone("UTC"));String timestamp =sdf.format(new Date());stringToSign.append("GET&%2F&");try {canonicalizedQueryString.append("AccessKeyId="+URLEncoder.encode(accessId,ENCODING)).append("&Action="+URLEncoder.encode("AssumeRole",ENCODING)).append("&Format="+URLEncoder.encode("JSON",ENCODING)).append("&GET=").append("&RoleArn="+URLEncoder.encode(arn,ENCODING)).append("&RoleSessionName="+URLEncoder.encode("client",ENCODING)).append("&SignatureMethod="+URLEncoder.encode("HMAC-SHA1",ENCODING)).append("&SignatureNonce="+URLEncoder.encode(uuid,ENCODING)).append("&SignatureVersion="+URLEncoder.encode("1.0",ENCODING)).append("&Timestamp="+URLEncoder.encode(timestamp,ENCODING)).append("&Version="+URLEncoder.encode("2015-04-01",ENCODING));stringToSign.append(URLEncoder.encode(canonicalizedQueryString.toString(),ENCODING));log.info("加签字符串:"+stringToSign.toString());String genHMAC = genHMAC(stringToSign.toString(),secretKey+"&");  reqBuilder.append("Format="+URLEncoder.encode("JSON",ENCODING)).append("&Version="+URLEncoder.encode("2015-04-01",ENCODING)).append("&AccessKeyId="+URLEncoder.encode(accessId,ENCODING)).append("&Signature="+URLEncoder.encode(genHMAC,ENCODING)).append("&SignatureMethod="+URLEncoder.encode("HMAC-SHA1",ENCODING)).append("&SignatureVersion="+URLEncoder.encode("1.0",ENCODING)).append("&SignatureNonce="+URLEncoder.encode(uuid,ENCODING)).append("&Timestamp="+URLEncoder.encode(timestamp,ENCODING)).append("&Action="+URLEncoder.encode("AssumeRole",ENCODING)).append("&GET=").append("&RoleArn="+URLEncoder.encode(arn,ENCODING)).append("&RoleSessionName="+URLEncoder.encode("client",ENCODING));} catch (UnsupportedEncodingException e1) {resp="{\"msg\":\"获取oss信息参数编码转换异常\"}";log.error("获取oss信息参数编码转换异常",e1);}try {String reqUrl="/?"+reqBuilder.toString();log.info("请求 获取临时的 oss 信息 地址:"+reqUrl);resp=HttpClientUtil.getRequest(reqUrl);JSONObject obj=JSON.parseObject(resp);obj.put("msg", "success");obj.put("desc", "success");resp=JSON.toJSONString(obj);log.info("阿里云返回的 oss 结果信息 :"+resp);} catch (Exception e) {JSONObject obj=new JSONObject();obj.put("msg", "failed");obj.put("desc", "获取临时的oss信息异常");resp=JSON.toJSONString(obj);log.error("获取临时的oss信息异常",e);}return resp;}/** * 使用 HMAC-SHA1 签名方法对data进行签名 *  * @param data  被签名的字符串 * @param key   密钥      * @return      加密后的字符串 */  public static String genHMAC(String data, String key) {  byte[] result = null;  try {  //根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称    SecretKeySpec signinKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);  //生成一个指定 Mac 算法 的 Mac 对象    Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);  //用给定密钥初始化 Mac 对象    mac.init(signinKey);  //完成 Mac 操作     byte[] rawHmac = mac.doFinal(data.getBytes());  result = Base64.encodeBase64(rawHmac);  } catch (Exception e) {  log.error("HMAC-SHA1 加密失败",e);}  if (null != result) {  return new String(result);  } else {  return null;  }  }  
}

https请求的工具类


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;import org.apachemons.collections.MapUtils;
import org.apachemons.httpclient.HttpClient;
import org.apachemons.httpclient.HttpConnectionManager;
import org.apachemons.httpclient.HttpStatus;
import org.apachemons.httpclient.MultiThreadedHttpConnectionManager;
import org.apachemons.httpclient.NameValuePair;
import org.apachemons.httpclient.methods.GetMethod;
import org.apachemons.httpclient.methods.PostMethod;
import org.apachemons.httpclient.methods.StringRequestEntity;
import org.apachemons.httpclient.params.HttpConnectionManagerParams;
import org.apachemons.httpclient.params.HttpMethodParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/** 
* @ClassName: GenTempOssUtil 
* @Description: 类HttpClientUtil.java的实现描述:httpclient工具类
* @author wenhuixiang
* @date 2018年5月30日 下午4:35:10 
*  
*/
public class HttpClientUtil {public static final String RETURN_CODE_FAIL = "request_fail";private final static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);private static final int timeout = 30000;/*** 每个主机最大连接数*/private static final int maxConnectionsPerHost = 20;/*** 最大总共连接数*/private static final int maxTotalConnection = 100;private static final String encoding = "UTF-8";private HttpClientUtil() {}/*** post请求** @param url    请求地址* @param params 请求参数* @return 返回结果* @throws Exception*/@SuppressWarnings("rawtypes")public static String postRequest(String url, Map<String, String> params) {return postRequest(url, null, params);}/*** post请求** @param url    请求地址* @param header 请求头* @param params 请求参数* @return 返回结果* @throws Exception*/@SuppressWarnings("rawtypes")public static String postRequest(String url, Map<String, String> header, Map<String, String> params) {String result = "";PostMethod postMethod = null;try {//创建连接HttpClient httpClient = new HttpClient(HttpClientUtilHolder.httpConnectionManager);// 设置编码httpClient.getParams().setContentCharset(encoding);httpClient.getParams().setHttpElementCharset(encoding);httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, encoding);postMethod = new PostMethod(url);//设置头信息if (MapUtils.isNotEmpty(header)) {for (Map.Entry<String, String> entry : header.entrySet()) {postMethod.setRequestHeader(entry.getKey(), entry.getValue());}}//设置参数List<NameValuePair> list = new ArrayList<NameValuePair>();NameValuePair nameValuePair = null;Iterator iter = params.entrySet().iterator();while (iter.hasNext()) {Map.Entry entry = (Map.Entry) iter.next();String key = (String) entry.getKey();String val = (String) entry.getValue();nameValuePair = new NameValuePair(key, val);list.add(nameValuePair);}NameValuePair[] data = list.toArray(new NameValuePair[list.size()]);postMethod.setRequestBody(data);//请求logger.info("=================httpclient发起请求");httpClient.executeMethod(postMethod);logger.info("=================httpclient请求结束");result = postMethod.getResponseBodyAsString();logger.info("httpclient请求结果:{}", result);} catch (Exception e) {logger.error("=================httpclient请求异常:", e);result = RETURN_CODE_FAIL;} finally {if (postMethod != null) {//释放连接postMethod.releaseConnection();}}return result;}/*** post请求-没有参数名,只有参数值** @param url  请求地址* @param body 请求参数* @return 返回结果* @throws Exception*/public static String postRequestOfNoParamName(String url, String body) {String result = "";PostMethod postMethod = null;try {//创建连接HttpClient httpClient = new HttpClient(HttpClientUtilHolder.httpConnectionManager);// 设置编码httpClient.getParams().setContentCharset(encoding);httpClient.getParams().setHttpElementCharset(encoding);httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, encoding);postMethod = new PostMethod(url);postMethod.setRequestEntity(new StringRequestEntity(body, "", encoding));//请求httpClient.executeMethod(postMethod);result = postMethod.getResponseBodyAsString();} catch (Exception e) {logger.error("=================httpclient请求异常异常:", e);result = RETURN_CODE_FAIL;} finally {if (postMethod != null) {//释放连接postMethod.releaseConnection();}}return result;}public static String getRequest(String url) throws Exception {String result = "";GetMethod getMethod = null;try {//创建连接HttpClient httpClient = new HttpClient(HttpClientUtilHolder.httpConnectionManager);// 设置编码httpClient.getParams().setContentCharset(encoding);httpClient.getParams().setHttpElementCharset(encoding);httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, encoding);getMethod = new GetMethod(url);//请求int statusCode = httpClient.executeMethod(getMethod);if (statusCode == HttpStatus.SC_OK) {result = getMethod.getResponseBodyAsString();} else {result = RETURN_CODE_FAIL;}} catch (Exception e) {logger.error("=================httpclient请求异常异常:", e);//          result = RETURN_CODE_FAIL;result = null;throw new Exception(e.getMessage(), e);} finally {if (getMethod != null) {//释放连接getMethod.releaseConnection();}}return result;}/*** 单例创建httpConnectionManager.*/private static class HttpClientUtilHolder {private static HttpConnectionManager httpConnectionManager = initConnectionManager();private static HttpConnectionManager initConnectionManager() {logger.info("initConnectionManager");httpConnectionManager = new MultiThreadedHttpConnectionManager();HttpConnectionManagerParams params = httpConnectionManager.getParams();params.setConnectionTimeout(timeout);params.setSoTimeout(timeout);params.setDefaultMaxConnectionsPerHost(maxConnectionsPerHost);params.setMaxTotalConnections(maxTotalConnection);return httpConnectionManager;}}}

结果示例

使用获取到的token信息上传文件

public static void main(String[] args) {String accessKeyId = "你获取到的accessKeyId";String accessKeySecret = "你获取到的secretKey";String securityToken = "你获取到的token";// 以杭州为例String endpoint = "";OSSClient client = new OSSClient(endpoint, accessKeyId, accessKeySecret, securityToken);ObjectMetadata meta = new ObjectMetadata();// 指定上传的内容类型。meta.setContentType("text/plain");UploadFileRequest fileReq=new UploadFileRequest("<yourBucketName>","<yourObjectName>");// 指定上传并发线程数,默认为1。fileReq.setTaskNum(5);// 指定上传的分片大小,从100KB到5GB,单位是Byte,默认为100K。fileReq.setPartSize(1 * 1024 * 1024);// 指定上传的本地文件,必选参数。fileReq.setUploadFile("C:\\Users\\Administrator\\Desktop\\123.png");//Object的元数据。fileReq.setObjectMetadata(meta);try {client.uploadFile(fileReq);} catch (Throwable e) {e.printStackTrace();}finally {if(client!=null) client.shutdown();}}

更多推荐

根据OSS子账户获取STS的TOKEN

本文发布于:2024-02-27 02:02:33,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1704788.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:账户   OSS   TOKEN   STS

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!