Authorization error on call to server-to-server CloudKit Web Services

吃可爱长大的小学妹 提交于 2019-12-05 02:06:27

问题


I'm attempting to implement some basic integration with CloudKit web services, following Apple's guide for authenticating requests. I've followed some help from this and this question as to how to properly authorize requests, and seem to be following all steps correctly, but I'm still getting a 401 AUTHENTICATION_FAILED error from Apple.

The endpoint I'm targeting is a POST endpoint for retrieving a record, given a record name.

I've added comments to my code to show the outputs i get at various stages, and I've used an alternative certificate so i'm not providing my genuine private key:

def self.signature(parameters, date, image_id)
    #date: 2016-08-14T14:32:20Z

    #parameters: {"records":[{"recordName":"7DBC4FAD-D18C-476A-89FB-14A515098F34"}]}

    encoded_parameters = Digest::SHA256.base64digest(parameters)

    #encoded_parameters: 6gmJ4AvmJgkNY4SJm6ImOxZaZ07J7cih/tRXI0zkRjQ=

    url_subpath = CloudKit.url_subpath

    #url_subpath: /database/1/iCloud.ProjectDent.TwIM/development/public/records/lookup

    message = date + ':' + encoded_parameters + ':' + url_subpath

    #message: 2016-08-14T14:23:35Z:6gmJ4AvmJgkNY4SJm6ImOxZaZ07J7cih/tRXI0zkRjQ=:/database/1/iCloud.ProjectDent.TwIM/development/public/records/lookup

    private_key = OpenSSL::PKey.read(File.read('altkey.pem'))

    signature = private_key.dsa_sign_asn1(OpenSSL::Digest::SHA256.digest(message))

    #signature: -? WX?xfc???ɔ???,?Ț?Փv?3+Xt!?$R?_Y?×*?,?3??Z-\#?ŭ?Ƿh

    encoded_signature = Base64.strict_encode64(signature)

    #encoded_signature: MEUCIFdYlHhmrxoIY8KW1tT6yZT17bYsP8ia09WTdpEzK1h0AiEA0yRSh39fWYHDlyqJLNgzhr9aLVwj2cWtkse3aA0tGZI=

    return encoded_signature
end

def self.headers(parameters, image_id)
    date = Time.now.utc.iso8601

    signature = self.signature(parameters, date, image_id)

    headers = {
        'X-Apple-CloudKit-Request-KeyID' => CloudKit.key_id,
        'X-Apple-CloudKit-Request-ISO8601Date' => date,
        'X-Apple-CloudKit-Request-SignatureV1' => signature
    }

    #headers (key id masked): {"X-Apple-CloudKit-Request-KeyID"=>"123456", "X-Apple-CloudKit-Request-ISO8601Date"=>"2016-08-14T14:32:20Z", "X-Apple-CloudKit-Request-SignatureV1"=>"MEUCIFdYlHhmrxoIY8KW1tT6yZT17bYsP8ia09WTdpEzK1h0AiEA0yRSh39fWYHDlyqJLNgzhr9aLVwj2cWtkse3aA0tGZI="}

    return headers
end

def self.fetch_image(image_id)
    url = CloudKit.url
    parameters = CloudKit.parameters(image_id).to_json
    headers = CloudKit.headers(parameters, image_id)

    begin
        response = RestClient.post(url, parameters, headers)
        puts 'response'
        puts response.code
        puts response.to_str
    rescue => e
        puts 'rescued: ' + e.to_s
    end
end

The end result is:

rescued: 401 Unauthorized

I'm not sure what I'm doing wrong here - I do seem to be following all steps correctly. Hopefully the logs can help someone understand where this might be going wrong.


回答1:


You need to convert the parameters to JSON before signing. And make sure to send the same JSON string as the signed copy.



来源:https://stackoverflow.com/questions/38943344/authorization-error-on-call-to-server-to-server-cloudkit-web-services

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!