REST API Azure 事件中心 ExpiredToken

REST API Azure Event Hub ExpiredToken

我正在使用 Rest 工具 Chrome 客户端测试 API 以验证我提出的 POST 请求是否正确,以便在 Java 应用。我的请求格式如下:

POST /androidhub/publishers/android/messages?timeout=60&api-version=2014-01 
HTTP/1.1 HOST: androidhub-124.servicebus.windows.net 
authorization: SharedAccessSignature sr=androidhub-124.servicebus.windows.net&sig=mykeySAS=&se=146480684&skn=RootManageSharedAccessKey 
content-type: application/json, application/atom+xml;type=entry;charset=utf-8 
content-length: 45  { "DeviceId":"dev-01", "Temperature":"37.0" }

但是我有以下错误。

<Error>
<Code>401</Code>
<Detail>ExpiredToken: . TrackingId:2f6d284e-d7d2-4c9c-81a5-79c542ce8eee_G7, SystemTracker:androidhub-124.servicebus.windows.net:androidhub/publishers/android/messages, Timestamp:5/25/2016 7:13:33 PM</Detail>
</Error>

密钥在我使用之前被重新生成了。我如何在不设置密钥过期时间的情况下不收到该错误或发出请求?

谢谢

根据我的经验,如果 se146480684 在这里是正确的 post,我认为问题是由 expiry 时间引起的,因为 se 键,以当前时间和 1970 年 1 月 1 日午夜 UTC 之间的秒数为单位。

所以 expiry 时间作为 se 键的值应该使用下面的 Java 代码得到。

long now = System.currentTimeMillis();
int expiry = (int)(now/1000) + 3600;

作为参考,你可以参考C#的官方文档,请看https://msdn.microsoft.com/en-us/library/azure/mt652140.aspx

除了设置正确的 se 值外,您还必须确保 sig 是经过加密签名(使用 HMAC 256)的 base64 字符串,其中包含命名空间(在您的情况下androidhub-124) 和 se,使用 SAS 密钥进行签名。

在 java 中生成 sig 的示例代码由 Microsoft here:

提供
private static String GetSASToken(String resourceUri, String keyName, String key)
{
    long epoch = System.currentTimeMillis()/1000L;
    int week = 60*60*24*7;
    String expiry = Long.toString(epoch + week);

    String sasToken = null;
    try {
        String stringToSign = URLEncoder.encode(resourceUri, "UTF-8") + "\n" + expiry;
        String signature = getHMAC256(key, stringToSign);
        sasToken = "SharedAccessSignature sr=" + URLEncoder.encode(resourceUri, "UTF-8") +"&sig=" +
                URLEncoder.encode(signature, "UTF-8") + "&se=" + expiry + "&skn=" + keyName;
    } catch (UnsupportedEncodingException e) {

        e.printStackTrace();
    }

    return sasToken;
}


public static String getHMAC256(String key, String input) {
    Mac sha256_HMAC = null;
    String hash = null;
    try {
        sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        Encoder encoder = Base64.getEncoder();

        hash = new String(encoder.encode(sha256_HMAC.doFinal(input.getBytes("UTF-8"))));

    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    return hash;
}