为azure服务总线/事件集线器生成有效的授权标头



我试图在ruby脚本中使用SAS身份验证,但我一直从事件中心收到401(拒绝访问)响应,似乎我生成的SAS令牌不正确。

以下是我使用的代码,它基于https://azure.microsoft.com/en-us/documentation/articles/service-bus-sas-overview/我已经重写为ruby的Javascript示例(请注意,它可能不是惯用的)

require "optparse"
require "CGI"
require 'openssl'
require "base64"
require "Faraday"
require 'Digest'
def generateToken(url,keyname,keyvalue)
    encoded = CGI::escape(url)
    ttl = (Time.now + 60*5).to_i
    signature = "#{encoded}n#{ttl}".encode('utf-8')
    # puts signature
    key = Base64.strict_decode64(keyvalue)
    dig  = OpenSSL::HMAC.digest('sha256', key, signature)
    # dig = Digest::HMAC.digest(signature, key, Digest::SHA256)
    hash = CGI.escape(Base64.strict_encode64(dig))
    # puts hash
    return "SharedAccessSignature sig=#{hash}&se=#{ttl}&skn=#{keyname}&sr=#{encoded}" 
end
def build_connection(url,token)
    conn = Faraday.new(:url => url) do |faraday|
        faraday.request  :url_encoded             # form-encode POST params
        faraday.response :logger                  # log requests to STDOUT
        faraday.adapter  Faraday.default_adapter  # make requests with Net::HTTP
    end
    conn.headers['Content-Type'] = 'application/json'
    conn.headers['Authorization'] = token
    return conn
end

if __FILE__ == $0
    ARGV << '-h' if ARGV.empty?
    options = {}
    OptionParser.new do |opts|
        opts.banner = "Usage: generateSasToken.rb [options]"
        opts.on('-u URL', '--url URL', 'url for access') { |v| options[:url] = v }
        opts.on('--keyname NAME','set key name') { |v| options[:keyname] = v }
        opts.on('--key KEY','set key value') { |v| options[:keyvalue] = v }
        opts.on_tail("-h", "--help", "Show this message") do
            puts opts
            exit
        end
    end.parse!
    token = generateToken(options[:url],options[:keyname],options[:keyvalue])
    puts token
    conn = build_connection(options[:url],token)
    puts conn.headers
    response =  conn.post do |req|
                    req.body = '{"temprature":50}'
                    req.headers['content-length'] = req.body.length.to_s
                end
    puts response
end

任何有助于理解令牌不正确的原因的帮助都将是很好的

将我的代码与python-sdk进行比较后,这是生成令牌的正确方法:

require "optparse"
require "CGI"
require 'openssl'
require "base64"
require "Faraday"
require 'Digest'
def generateToken(url,keyname,keyvalue)
    encoded = CGI::escape(url)
    ttl = (Time.now + 60*5).to_i
    signature = "#{encoded}n#{ttl}"
    # puts signature
    key = keyvalue
    #dig  = OpenSSL::HMAC.digest('sha256', key, signature)
    dig = Digest::HMAC.digest(signature, key, Digest::SHA256)
    hash = CGI.escape(Base64.strict_encode64(dig))
    # puts hash
    return "SharedAccessSignature sig=#{hash}&se=#{ttl}&skn=#{keyname}&sr=#{encoded}" 
end
def build_connection(url,token)
    conn = Faraday.new(:url => url) do |faraday|
        faraday.request  :url_encoded             # form-encode POST params
        faraday.response :logger                  # log requests to STDOUT
        faraday.adapter  Faraday.default_adapter  # make requests with Net::HTTP
    end
    conn.headers['Content-Type'] = 'application/json'
    conn.headers['Authorization'] = token
    return conn
end

if __FILE__ == $0
    ARGV << '-h' if ARGV.empty?
    options = {}
    OptionParser.new do |opts|
        opts.banner = "Usage: generateSasToken.rb [options]"
        opts.on('-u URL', '--url URL', 'url for access') { |v| options[:url] = v }
        opts.on('--keyname NAME','set key name') { |v| options[:keyname] = v }
        opts.on('--key KEY','set key value') { |v| options[:keyvalue] = v }
        opts.on_tail("-h", "--help", "Show this message") do
            puts opts
            exit
        end
    end.parse!
    token = generateToken(options[:url],options[:keyname],options[:keyvalue])
    conn = build_connection(options[:url],token)
    puts conn.headers
    response =  conn.post do |req|
                    req.body = '{"temprature":50}'
                    req.headers['content-length'] = req.body.length.to_s
                end
    puts response
end

这比预期的要简单得多,不需要编码到utf8或解码密钥。

相关内容

最新更新