AstroCanvas分享页Token签名校验使用说明
通过Token参数签名校验功能,可以对大屏交互时传递的URL进行签名鉴权,保证大屏的URL访问链接不会被篡改,从而提高大屏数据以及用户信息的安全性。
前提条件
在使用Token签名验证功能前,需满足以下条件:
- AstroCanvas大屏页面,使用Token验证的方式进行发布。
- AstroCanvas大屏页面,以Get的方式在URL中传递参数,且必须带有_dmax_signature、_dmax_time参数。
- AstroCanvas大屏URL未被篡改。
背景信息
用户开启了Token签名验证功能,系统返回用以生成签名的Token(用于生成签名的token不可公开),例如token=j5TZLK1DQ*****Ntquo/ErqonR0=。
假设,某用户系统嵌入了AstroCanvas大屏页面,通过Token计算签名,最终得到的分享页面链接为(如果对该分享链接进行了篡改,那么页面将无法访问):
https://dmax.***.com/magno/render/share/xxx?_dmax_time=1669621495545&name=cloud&age=36&dept=cloud&_dmax_signature=DVX7Qy******o5rs%3D
其中:
- _dmax_time=1669621495545:为AstroCanvas页面用户分享链接生成时间戳。如果开启了有效期设置,_dmax_time值要小于有效期值,单位为毫秒时间戳。
- _dmax_signature=DVX7Qy******o5rs%3D:为Token对URL进行计算得出的签名,用于身份验证。
- name=cloud&age=36&dept=cloud:为用户自定义扩展参数。
分享URL签名说明
Token签名校验,是针对整个URL计算并得出的签名。其中,“_dmax_time”为签名生成时的时间戳(该参数值可自定义,默认为计算签名时的时间)。“_dmax_signature”为最终对URL进行计算得出的签名。
在计算签名时,会对参数按照key升序排序,且将多个相同key的参数值进行合并。
例如,用于计算签名的URL输入如下:
https://dmax.***.com/magno/render/share/xxx?_dmax_time=1669621495545&name=cloud&age=35&dept=cloud&age=36
则通过对参数排序,相同参数合并后(例如age),得到的用于计算的URL为:
https://dmax.***.com/magno/render/share/xxx?_dmax_time=1669621495545&age=35,36&dept=cloud&name=cloud
URL签名计算代码示例
以Java代码为例,URL签名计算代码示例如下:
private String getSignature(String uri, TreeMap<String, String[]> parameterMap, String token) { List<String> parameterList = parameterMap.entrySet() .stream() .map(entry -> entry.getKey() + "=" + String.join(",", entry.getValue())) .collect(Collectors.toList()); // 对参数进行排序 String sortParams = String.join("&", parameterList); // 重新拼接参数 String usedSigUrl = String.join("?", new String[] {uri, sortParams}); String signature = Objects.requireNonNull( HMACSHA256(usedSigUrl.getBytes(StandardCharsets.UTF_8), token.getBytes(StandardCharsets.UTF_8))); return signature; } private String HMACSHA256(byte[] data, byte[] key) { try { SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA256"); Mac mac = Mac.getInstance("HmacSHA256"); mac.init(signingKey); return URLEncoder.encode(byte2Base64(mac.doFinal(data)), StandardCharsets.UTF_8.name()); } catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) { e.printStackTrace(); } return ""; } private String byte2Base64(byte[] bytes) { return Base64.encodeBase64String(bytes); } public void getSignatureUrl() { String cusUrl = "https://dmax.test.com/magno/render/share/xxx?name=cloud&age=36&dept=cloud"; // 待签名计算url String uri = "https://dmax.test.com/magno/render/share/xxx"; // uri String token = "xxxx"; // 页面分享认证token String timestamp = String.valueOf(new Date().getTime()); // 时间戳 TreeMap<String, String[]> parameterMap = new TreeMap<>(); // 参数集合 parameterMap.put("name", new String[] {"cloud"}); parameterMap.put("age", new String[] {"36"}); parameterMap.put("dept", new String[] {"cloud"}); parameterMap.put("_dmax_time", new String[] {timestamp}); String signature = getSignature(uri, parameterMap, token); String inputUrl = cusUrl + "&" + "_dmax_time=" + timestamp; // 将分享链接url拼接上时间戳参数 System.out.println(String.join("&", inputUrl, "_dmax_signature=" + signature)); // 打印输出 }
使用以上代码示例,得到的可访问签名的分享链接为:
https://dmax.***.com/magno/render/share/xxx?name=cloud&age=36&dept=cloud&_dmax_time=1669639799495&_dmax_signature=2Lbxef1HvbIx4kd9pBjmHswAa******xlBu3o9M%3D
在URL有效期内,如果篡改了该URL任何一处,链接将无法访问。