2012-11-16 37 views
5

我想使用R包httr通過他們的API訪問EC2服務。但是我不確定如何開始,因爲它不屬於通常的:密鑰,祕密,令牌和簽名系統的「Oauth2.0」認證格式。我認爲EC2使用「簽名版本2」方法,但我不清楚它是如何工作的。R + httr和EC2 API認證問題

望着那EC2關於使查詢請求在http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/using-query-api.html

我想我需要簽字的價值提供了文檔....但不知道如何得到它

我有嘗試使用一些給定的命令使用httr,如下所示。我可以調整URL字符串中的大部分參數來表示我和我想要做的事情,例如AWSAccessKeyId,ImageId,endpointAction等等......但是不知道從哪裏去獲取簽名值。

在一些給出的例子

而且,他們不似乎要麼提供的祕密訪問鍵...

所以試圖命令如下具有改變一些值來代表我,但有以下幾點:

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") 

,而我得到的迴應:

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="" /> ... 

有沒有人曾與EC2 API及其認證過程的經驗和其將b e很容易使用R能夠使用我選擇的AMI(其中包含R和其他相關軟件包)來設置和運行Linux實例,然後在這些實例中運行一些R命令,並將輸出恢復?

不要以爲它真的與我sessionInfo但萬一這裏是:

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 

編輯:

因此,在進一步企圖按照文檔由@建議哈德利這是我的嘗試和得到...任何更多的有用的提示,我會出錯的地方將不勝感激...:

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) 

我得到的迴應:

Response [https://ec2.amazonaws.com?Action=DescribeImages&ImageId.1=[ami.number.from.before]&Version=2012-10-01&Expires=2012-11-20T12%3A00%3A00Z&Signature=[sig.value.from.before]&SignatureVersion=2&SignatureMethod=HmacSHA1&AWSAccessKeyId=[aws.key.from.before]/] 
    Status: 401 
    Content-type: 
<?xml version="1.0" encoding="UTF-8"?> 
<Response><Errors><Error><Code>AuthFailure</Code><Message>AWS was not able to validate the provided access credentials</Message></Error></Errors><RequestID>5e10fb0b-f304-4677-9c64-98b4537c659a</RequestID></Response> 
+0

用於生成簽名的基本算法在http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/using-query-api.html#query-authentication佈置 - 'httr'具有步驟3的'hmac'功能。 – hadley

+0

謝謝...我看到了,但並不確定我明白了它的含義......有沒有可能提供一個示例? –

+0

或者在我編輯時可能會看到我要出錯的地方?我想即時關閉... –

回答

6

這是我的嘗試在逐步轉換算法到R代碼。根據我的經驗,您確實需要分開執行每一步,以便您可以在每個階段檢查結果是否正確。

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

對不起,也許我錯過了一些東西,但我該如何處理params對象?能夠使用'httr'的GET函數 –

+0

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

+0

hmm ...似乎仍然從GET的響應中獲得錯誤代碼(「https://ec2.amazonaws .com「,query = params)',得到:'SignatureDoesNotMatch我們計算的請求籤名與您提供的簽名不匹配。檢查您的AWS祕密訪問密鑰和簽名方法。詳細信息請參閱服務文檔。'祕密和訪問的價值看起來很好... –