HTTP POST Azure中的授权标头[错误代码401]

时间:2018-09-04 08:10:51

标签: python c azure azure-eventhub

我正在关注this link,以便对Azure中的Eventhub进行HTTP POST。我得到的错误是401 40103:无效的授权令牌签名。根据Azure,POST应该具有以下格式:

POST https://your-namespace.servicebus.windows.net/your-event-hub/partitions/0/messages?timeout=60&api-version=2014-01 HTTP/1.1  
Authorization: SharedAccessSignature sr=your-namespace.servicebus.windows.net&sig=your-sas-key&se=1403736877&skn=RootManageSharedAccessKey  
Content-Type: application/atom+xml;type=entry;charset=utf-8  
Host: your-namespace.servicebus.windows.net  

关于Authorization标头,我有几个问题:

  1. 我的秘密密钥(sig)具有等号,如果我将其替换为 %3d?
  2. 我目前还在使用 来自Azure的Python和C中的示例脚本。在这些示例中,是 仅需要引入具有所有凭据的端点,并且 发布/获取操作正常。是否可以执行 放置/获取操作直接在api中引入端点 休息,或获取下面执行的授权标头 python还是c代码?

谢谢。

1 个答案:

答案 0 :(得分:1)

我可以通过在命名空间而不是在事件中心上创建SAS策略(下面的nssend)来使其工作。

$ curl -X POST -i "https://breakingnews.servicebus.windows.net/sucheventsmuchwow/messages" \
    -H "Authorization: SharedAccessSignature sr=https%3A%2F%2Fbreakingnews.servicebus.windows.net%2Fsucheventsmuchwow%2Fmessages&sig=SAS_SIG_GOES_HERE&se=1536733370&skn=nssend" \
    -H "Content-Type: application/json" \
    --data-ascii "{ \"message\": \"So many events, so little time.\" }"


HTTP/1.1 201 Created
Server: Microsoft-HTTPAPI/2.0
...

那行得通。

但是,当您使用事件中心级SAS策略生成签名(与名称空间级策略相对)时,就像您一样,我得到了HTTP 401

这就是我用来生成SAS令牌的东西-

// Make a SAS token
// See https://docs.microsoft.com/en-us/rest/api/eventhub/generate-sas-token
// Appologies for JavaScript
// npm install moment

const moment = require('moment');
const crypto = require('crypto');

function create_sas_token(uri, key_name, key)
{
    // Token expires in one hour
    var expiry = moment().add(7, 'days').unix();

    var string_to_sign = encodeURIComponent(uri) + '\n' + expiry;
    var hmac = crypto.createHmac('sha256', key);
    hmac.update(string_to_sign);
    var signature = hmac.digest('base64');
    var token = 'SharedAccessSignature sr=' +
        encodeURIComponent(uri) +
        '&sig=' + encodeURIComponent(signature) +
        '&se=' + expiry + '&skn=' + key_name;

    return token;
}

let token = create_sas_token('https://breakingnews.servicebus.windows.net/sucheventsmuchwow/messages', 'MySendPolicy', 'MySendPolicyPrimaryKey=');

console.log(token);

更新

感谢Clemens巨星—

  

尝试省略“ / messages”

—克莱门斯·韦斯特(Clemens Vasters),信使(@clemensv)September 5, 2018

您要签名的字符串(资源URI)应省略/messages,例如

create_sas_token('https://breakingnews.servicebus.windows.net/sucheventsmuchwow',
    'MyEventHubLevelPolicy', 'hUbPriMAry/KEy=');

然后按照以下步骤设计您的请求-

$ curl -X POST -i "https://breakingnews.servicebus.windows.net/sucheventsmuchwow/messages" \
    -H "Authorization: SharedAccessSignature sr=https%3A%2F%2Fbreakingnews.servicebus.windows.net%2Fsucheventsmuchwow&sig=DONT_INCLUDE_/MESSAGES_IN_STRING_TO_SIGN&se=1536757127&skn=MyEventHubLevelPolicy" \
    -H "Content-Type: application/json" \
    --data-ascii "{ \"message\": \"SAS signed with Event Hub level policy\" }"


HTTP/1.1 201 Created
Server: Microsoft-HTTPAPI/2.0
...

TL; DR:

您的POST URL应该包含结尾的/messages,但是要签名的字符串(资源URI)应该不包含。总是。无论使用命名空间还是集线器范围的策略。