ruby on rails - Error de autorización en la llamada a los servicios web CloudKit de servidor a servidor
ruby-on-rails openssl (1)
Necesita convertir los parámetros a JSON antes de firmar. Y asegúrese de enviar la misma cadena JSON como la copia firmada.
Estoy intentando implementar una integración básica con los servicios web de CloudKit, siguiendo la guía de Apple para autenticar solicitudes. He seguido la ayuda de esta y la siguiente pregunta sobre cómo autorizar correctamente las solicitudes, y parece que estoy siguiendo todos los pasos correctamente, pero todavía recibo un error 401 AUTHENTICATION_FAILED
de Apple.
El objetivo al que estoy apuntando es un punto final POST para recuperar un registro, dado un nombre de registro.
He agregado comentarios a mi código para mostrar las salidas que recibo en varias etapas, y he usado un certificado alternativo, así que no estoy proporcionando mi clave privada genuina:
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
El resultado final es:
rescatado: 401 no autorizado
No estoy seguro de lo que estoy haciendo mal aquí. Parece que estoy siguiendo todos los pasos correctamente. Con suerte, los registros pueden ayudar a alguien a entender dónde podría estar yendo mal.