2012-11-16 18 views
5

Ich möchte das R-Paket httr verwenden, um über ihre API auf die EC2-Dienste zuzugreifen. Aber ich bin ein wenig unsicher, wie ich anfangen soll, da es nicht in das übliche Authentifizierungsformat von "Oauth2.0" fällt, in dem Sie das übliche Schlüssel-, Geheimnis-, Token- und Signatursystem haben. Ich denke, EC2 verwendet die "Signature Version 2" -Methode, aber ich weiß nicht, wie das funktioniert.R + httr und EC2 api Authentifizierungsprobleme

in der Dokumentation suchen, die EC2 in Bezug auf http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/using-query-api.html zu machen Abfrageanforderungen bietet

Ich glaube, ich den Wert für Unterschrift müssen .... aber nicht wissen, wie es zu bekommen

Ich habe versucht, einige der angegebenen Befehle mit httr wie unten gezeigt. Ich kann die meisten Parameter in der URL-Zeichenkette anpassen, um mich und die Sachen darzustellen, die ich tun möchte, z. B. AWSAccessKeyId, ImageId, endpoint und die Action usw. .... aber wissen Sie nicht, wohin man den Unterschriftswert erhält.

Auch in einigen der Beispiele gegeben, sie scheinen nicht, entweder den geheimen Zugriffsschlüssel zur Verfügung zu stellen ...

Also die versucht Befehle sind wie folgt mir zu repräsentieren einige der Werte verändert haben, aber bekam die folgende:

require(httr) 
GET("https://ec2.amazonaws.com/ 
?Action=RunInstances 
&ImageId=ami-60a54009 
&MaxCount=3 
&MinCount=1 
&Placement.AvailabilityZone=us-east-1b 
&Monitoring.Enabled=true 
&AWSAccessKeyId=0GS7553JW74RRM612K02EXAMPLE 
&Version=2012-10-01 
&Expires=2010-10-10T12:00:00Z 
&Signature=lBP67vCvGlDMBQ1dofZxg8E8SUEXAMPLE 
&SignatureVersion=2 
&SignatureMethod=HmacSHA256") 

zu denen bekomme ich die Antwort:

Response [http://aws.amazon.com/ec2/] 
    Status: 200 
    Content-type: text/html; charset=UTF-8 


    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 

<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
    <link rel="icon" type="image/ico" href="//d36cz9buwru1tt.cloudfront.net/favicon.ico"> 
    <link rel="shortcut icon" type="image/ico" href="//d36cz9buwru1tt.cloudfront.net/favicon.ico"> 
    <meta name="description" content="Amazon Elastic Compute Cloud delivers scalable, pay-as-you-go compute capacity in the cloud. " /><meta name="keywords" content="" /> ... 

hat jemand Erfahrung mit der EC2 api hatte und seine Authentifizierungsverfahren und würde es b Es ist einfach genug, R zu verwenden, um Linux-Instanzen mit von mir ausgewählten AMIs einzurichten und zu betreiben (mit R und anderen relevanten Paketen), dann einige R-Befehle in diesen Instanzen auszuführen und die Ausgabe zurück zu bringen?

Glauben Sie nicht, es ist wirklich zu meiner Session verwendet, aber nur für den Fall hier ist sie:

sessionInfo() 
R version 2.15.1 (2012-06-22) 
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit) 

locale: 
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8 

attached base packages: 
[1] stats  graphics grDevices utils  datasets methods base  

other attached packages: 
[1] httr_0.2 

loaded via a namespace (and not attached): 
[1] digest_0.5.2 plyr_1.7.1  RCurl_1.95-1.1 stringr_0.6.1 tools_2.15.1 

EDIT:

So in einem weiteren Versuch, der Dokumentation zu folgen, wie von @ vorgeschlagen Hadley das ist, was ich versucht und bekam ... noch mehr hilfreiche Hinweise darüber, wo im gehend falsch wäre sehr dankbar ...:

require(httr) 

aws.key <- "xxxxxxx" 
aws.secret <- "xxxxxxxxxxxx" 

verb <- "GET" 
zone <- "ec2.amazonaws.com" 
func <- "DescribeImages" 

ami.number <- "ami-xxxxxxxxx" 

params <- list(paste0("ImageId.1=",ami.number), 
    "Version=2012-10-01", 
    "Expires=2012-11-20T12%3A00%3A00Z") 


# adding in method and key parameters for creation of string to sign 
orig.len.params <- length(params) 
params.w.method.key <- params 
params.w.method.key[[orig.len.params+1]] <- "SignatureVersion=2" 
params.w.method.key[[orig.len.params+2]] <- "SignatureMethod=HmacSHA1" 
params.w.method.key[[orig.len.params+3]] <- paste0("AWSAccessKeyId=",aws.key) 

# String to sign (s2s) 
s2s <- paste(c(paste0(verb,"\n",zone,"\n","/\n","AWSAccessKeyId=",aws.key),paste0("Action=",func),paste(sort(unlist(params.w.method.key)),collapse="&")),collapse="&") 

# Signature(sig) 
sig <- hmac_sha1(aws.secret, s2s) 

# adding in signature, method and key parameters for signed request url generation 
params.w.sig.method.key <- params 
params.w.sig.method.key[[orig.len.params+1]] <- paste0("Signature=",sig) 
params.w.sig.method.key[[orig.len.params+2]] <- "SignatureVersion=2" 
params.w.sig.method.key[[orig.len.params+3]] <- "SignatureMethod=HmacSHA1" 
params.w.sig.method.key[[orig.len.params+4]] <- paste0("AWSAccessKeyId=",aws.key) 

# Signed request (sr) 
sr <- paste(c(paste0("https://",zone,paste0("?Action=",func)),paste(unlist(params.w.sig.method.key),collapse="&")),collapse="&") 

# GET signed request 
GET(sr) 

, auf die ich die Antwort erhalte:

+0

Der grundlegende Algorithmus, um die Signatur zur Erzeugung in http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/using-query-api.html#query-authentication angelegt - 'httr' das hat 'hmac' Funktion für Schritt 3. – hadley

+0

danke ... ich sah das, war mir aber nicht wirklich sicher, dass ich verstand, was es bedeutete ... Gibt es eine Möglichkeit, ein Beispiel zu geben? –

+0

oder möglicherweise sehen, wo ich falsch liege angesichts meiner Änderungen? Ich denke ich bin nah dran ... –

Antwort

6

Hier ist mein Versuch einer Schritt für Schritt Umwandlung des Algorithmus in R-Code. Meiner Erfahrung nach wollen Sie jeden Schritt einzeln durchführen, damit Sie in jeder Phase überprüfen können, ob die Ergebnisse korrekt sind.

require("httr") 
require("RCurl") 
require("stringr") 

# 0: get key and secret from envvars, and set up request parameters 

aws.key <- Sys.getenv("AWS_KEY") 
aws.secret <- Sys.getenv("AWS_SECRET_KEY") 

verb <- "GET" 
zone <- "ec2.amazonaws.com" 

ami.number <- "ami-xxxxxxxxx" 

params <- list(
    Action = "DescribeImages", 
    ImageId.1 = ami.number, 
    Version = "2012-10-01", 
    Expires = "2012-11-20T12:00:00Z", 
    SignatureVersion = 2, 
    SignatureMethod = "HmacSHA1", 
    AWSAccessKeyId = aws.key) 

# 1a: Sort the UTF-8 query string components by parameter name 
params <- params[order(names(params))] 

# 1b: URL encode the parameter name and values 
params_e <- lapply(params, curlEscape) 
names(params_e) <- curlEscape(names(params_e)) 
params_str <- str_c(names(params_e), "=", unlist(params_e), collapse = "&") 
params_str <- gsub("%2E",".",gsub("%2D","-",params_str)) 

# 2: Create the string to sign 
string_to_sign <- str_c(
    toupper(verb), "\n", 
    tolower(zone), "\n", 
    "/", "\n", 
    params_str 
) 

# 3: Calculate an RFC 2104-compliant HMAC 
# 4: Convert the resulting value to base64. 
hmac <- hmac_sha1(aws.secret, string_to_sign) 

params$Signature <- hmac 

GET(paste0("https://",zone),query=params) 
+0

Sorry vielleicht fehlt mir etwas aber was mache ich mit dem params objekt?um die GET-Funktion von 'httr' zu verwenden –

+0

' GET (url, query = params) ' – hadley

+0

hmm ... scheinen immer noch einen Fehlercode aus der Antwort von' GET ("https: //ec2.amazonaws .com ", query = params)', getting: 'SignatureDoesNotMatch Die von uns berechnete Anforderungssignatur stimmt nicht mit der von Ihnen angegebenen Signatur überein. Überprüfen Sie den geheimen AWS-Zugriffsschlüssel und die Signaturmethode. Weitere Informationen finden Sie in der Servicedokumentation. 'die Werte von Geheimnis und Zugang sehen gut aus ... –