【问题标题】:Authorization header in HTTP POST Azure [Error code 401]HTTP POST Azure 中的授权标头 [错误代码 401]
【发布时间】:2018-09-04 08:10:51
【问题描述】:

我关注 this link 是为了向 Azure 中的 Eventhub 发送 HTTP POST。我得到的错误是 401 40103:无效的授权令牌签名。根据 Azure,POST 应具有以下格式:

发布 https://your-namespace.servicebus.windows.net/your-event-hub/partitions/0/messages?timeout=60&api-version=2014-01 HTTP/1.1 授权:SharedAccessSignature sr=your-namespace.servicebus.windows.net&sig=your-sas-key&se=1403736877&skn=RootManageSharedAccessKey 内容类型:application/atom+xml;type=entry;charset=utf-8 主机:your-namespace.servicebus.windows.net

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

  1. 我的密钥 (sig) 有一个等号,我应该将其替换为 %3d?
  2. 我目前也在做 POST 操作 Azure 中的 Python 和 C 语言示例脚本。在这些例子中,是 只需要引入具有所有凭据的端点和 发布/获取操作工作正常。是否可以执行 在 api 中直接引入端点的 put/get 操作 休息,或获取下面执行的授权标头 python还是c代码?

谢谢。

【问题讨论】:

  • 您能否展示一下您目前正在从 REST 执行的 POST 操作? C 和 Python API 工作的原因是它们在后台构建 REST 请求。
  • 当然!这是目前我的 POST 消息 curl -X POST -k -H 'Content-Type: application/atom+xml;type=entry;charset=utf-8' -H 'Authorization: SharedAccessSignature sr=mynamespace.servicebus.windows.net&sig =mysignature&se=1803736877&skn=RootManageSharedAccessKey' -i 'mynamespace.servicebus.windows.net/myeventhub/…' --data '{ "DeviceId":"dev-01", "Temperature":"37.0" }'
  • 看起来是正确的。关于你的第一个问题,+ %3d,我相信它应该被编码,所以最好这样做。还要确保您的到期(se 字段)未设置为过去的某个值。这也会导致 401。
  • api-version 看起来不对。
  • @evilSnobu 为什么?

标签: python c azure azure-eventhub


【解决方案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 Vasters —

尝试省略“/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)不应包含。总是。无论是使用命名空间还是 Hub 范围的策略。

【讨论】:

    猜你喜欢
    • 2011-06-23
    • 2013-12-29
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 2015-12-11
    • 2021-12-15
    • 2014-06-24
    • 2020-04-12
    相关资源
    最近更新 更多