Ошибка авторизации при вызове межсерверных веб-служб CloudKit

Я пытаюсь реализовать некоторую базовую интеграцию с веб-службами CloudKit, следуя руководству Apple по аутентификации запросов. Я следил за некоторой помощью от этот и этот вопрос о том, как правильно разрешаю запросы и, похоже, правильно выполняю все шаги, но я все еще получаю сообщение об ошибке 401 AUTHENTICATION_FAILED от Apple.

Конечная точка, на которую я нацелился, является конечной точкой POST для извлечения записи с заданным именем записи.

Я добавил комментарии к своему коду, чтобы показать результаты, которые я получаю на разных этапах, и я использовал альтернативный сертификат, поэтому я не предоставляю свой подлинный закрытый ключ:

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

Конечный результат:

спасено: 401 несанкционированный

Я не уверен, что я делаю неправильно здесь - кажется, я правильно выполняю все шаги. Надеюсь, журналы могут помочь кому-то понять, где это может пойти не так.


person Andrew    schedule 14.08.2016    source источник


Ответы (1)


Перед подписанием необходимо преобразовать параметры в JSON. И обязательно отправьте ту же строку JSON, что и подписанная копия.

person Alexsander Akers    schedule 14.08.2016
comment
Спасибо. Я отредактировал его, чтобы он соответствовал этому решению, которое работает. Надеюсь, кто-то сможет использовать это для своих собственных запросов. - person Andrew; 14.08.2016