在Android上生成Azure SAS令牌

尝试生成Azure SAS令牌以便能够使用Service Bus REST Api。

找到此链接:

http://blog.simontimms.com/2015/01/30/sending-message-to-azure-service-bus-using-rest/

如何在Android上实现相同的目标?

我目前的尝试看起来像这样:

private String generateSasToken(String uri, String keyName, String key){ String ret = ""; long tokenExpirationTime = (System.currentTimeMillis() / 1000) + (10 * 365 * 24 * 60 * 60); try { String stringToSign = new URL(uri).toString() + "\n" + tokenExpirationTime; SecretKey secretKey = null; byte[] keyBytes = key.getBytes("UTF-8"); Mac mac = Mac.getInstance("HMACSHA256"); secretKey = new SecretKeySpec(keyBytes, mac.getAlgorithm()); mac.init(secretKey); String signature = Base64.encodeToString(mac.doFinal(stringToSign.getBytes("UTF-8")), Base64.DEFAULT); ret = String.format("SharedAccessSignature sr=%s&sig=%s&se=%s&skn=%s", URLEncoder.encode(uri), URLEncoder.encode(signature), String.valueOf(tokenExpirationTime), keyName); } catch (MalformedURLException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return ret; } 

在使用Postman调用服务总线的Rest API后,我得到以下结果:

401 40103:无效的授权令牌签名时间261毫秒


更新:找到此链接

https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-android-get-started/

根据第6节,android的代码

我没有Android环境要测试,我在java环境中有类似的场景,它工作正常,以下是我的代码:

 private static String generateSasToken(String uri, String keyName, String key){ String ret = ""; // long tokenExpirationTime = (System.currentTimeMillis() / 1000) + (10 * 365 * 24 * 60 * 60); Date now = new Date(); Date previousDate=new Date(1970); long tokenExpirationTime = ((now.getTime() - previousDate.getTime()) / 1000 )+3600; try { String stringToSign = URLEncoder.encode(new URL(uri).toString(),java.nio.charset.StandardCharsets.UTF_8.toString()) + "\n" + tokenExpirationTime; System.out.println(stringToSign); SecretKey secretKey = null; byte[] keyBytes = key.getBytes("UTF-8"); Mac mac = Mac.getInstance("HMACSHA256"); secretKey = new SecretKeySpec(keyBytes, mac.getAlgorithm()); mac.init(secretKey); byte[] digest = mac.doFinal(stringToSign.getBytes()); //We then use the composite signing key to create an oauth_signature from the signature base string String signature = Base64.encodeBase64String(digest); System.out.println( URLEncoder.encode(signature, java.nio.charset.StandardCharsets.UTF_8.toString())); // String signature = Base64.encodeBase64String(mac.doFinal(stringToSign.getBytes("UTF-8"))); ret = String.format("SharedAccessSignature sr=%s&sig=%s&se=%s&skn=%s", URLEncoder.encode(uri, java.nio.charset.StandardCharsets.UTF_8.toString()), URLEncoder.encode(signature, java.nio.charset.StandardCharsets.UTF_8.toString()), String.valueOf(tokenExpirationTime), keyName); } catch (MalformedURLException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return ret; } 

我已经改变了两个地方,1)tokenExpirationTime 2)URLEncoder.encode字符串stringTosign,请尝试我的建议,希望这可以给你一些提示。

我不知道这是否对您有所帮助,但这是C#中的一个示例:

 class Program { static void Main(string[] args) { var sasToken = createToken("yournamespace.servicebus.windows.net”, "device_send_listen", "xxxxxxx"); } private static string createToken(string resourceUri, string keyName, string key) { TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1); var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + 3600); //EXPIRES in 1h string stringToSign = HttpUtility.UrlEncode(resourceUri) + "\n" + expiry; HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key)); var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign))); var sasToken = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}", HttpUtility.UrlEncode(resourceUri), HttpUtility.UrlEncode(signature), expiry, keyName); return sasToken; } }