有没有办法以编程方式处理S3 RequestTimeTooSkewed错误而不更改本地时钟

时间:2014-12-08 21:35:46

标签: .net amazon-web-services amazon-s3

我已在网上阅读了有关此问题的所有内容。我知道支票是由亚马逊完成的,我无法控制它。

问题是我的程序可以安装在数百台桌面上。我无法修复所有这些桌面的时钟。

我可以从服务器调用中获取正确的时间并计算时间偏差。无论如何通过AWS .NET SDK将固定时间传递给亚马逊,以便时间偏差错误消失?

我已经尝试传递请求标头 - 它不起作用。

putRequest.Headers["Date"] = time;
putRequest.Headers["x-amz-date"] = time;

2 个答案:

答案 0 :(得分:1)

经过广泛的研究,我找到了答案。最新的AWS开发工具包中存在一个错误,它不允许您指定的日期实际进入S3。所以目前的API:

  1. 忽略通过API中的标头传递的时间值。无论如何,x-amz-date肯定会被覆盖。

  2. 使用偏斜本地时钟的默认时间为授权者构建签名。

  3. 要解决此问题,请从Amazon下载the latest AWS SDK source code。我执行了以下操作以确保日期和x-amz-date相同,并将传递给API的值:

    AWS-SDK净主\ AWSSDK_DotNet35 \ Amazon.Runtime \管道\的HttpHandler \ HttpHandler.cs:

    public override void InvokeSync(IExecutionContext executionContext)
    
    • 如果x-amz-date中的wrappedRequest.Headers和日期存在,并且它们不相等,请从日期设置x-amz-date

    AWS-SDK净主\ AWSSDK_DotNet35 \ Amazon.Runtime \内部\验证\ AWS3Signer.cs:

    private static void SignHttp(IRequest request, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey)
    private static void SignHttps(IRequest request, ClientConfig clientConfig, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey)
    
    • 如果request.Headers包含x-amz-date标题,请将“date”局部变量设置为它,否则将其设置为日期标题中传递的值。

    AWS-SDK净主\ AWSSDK_DotNet35 \ Amazon.Runtime \内部\验证\ S3Signer.cs:

    internal void SignRequest(IRequest request, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey)
    
    • 如果request.Headers不包含x-amz-date标题并且确实包含日期标题,请设置日期标题中的值,否则只需让它执行当前的操作。

    AWS-SDK净主\ AWSSDK_DotNet35 \ Amazon.Runtime \内部\验证\ CloudFrontSigner.cs:

    public override void Sign(IRequest request, ClientConfig clientConfig, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey)
    
    • 如果request.Headers包含x-amz-date标题,请为其设置“dateTime”局部变量,否则将其设置为日期标题中传递的值。

    重要:

    使用这些代码更改进行编译后,使用以下命令将时间传递给API调用请求:

    //DATE TIME HAS TO BE IN THIS FORMAT
    string time = AWSSDKUtils.GetFormattedTimestampRFC822(<time skew in minutes>); 
    request.Headers[HeaderKeys.DateHeader] = time;
    request.Headers[HeaderKeys.XAmzDateHeader] = time;
    

    可以通过从任何服务器获取日期并减去当地时间来找出时间偏差。但请注意,时间偏差会在VM上发生变化,有时会变得更糟,有时会自行纠正。

答案 1 :(得分:0)

您可以发送完成处理程序请求和响应,它可以设置您的偏斜时间,然后您可以重新发送您的请求。 如果您的时间超过5个月,亚马逊服务器将不允许我们做任何事情,所以当时间超过5个月时它不会帮助

//403 code have clockskew error but 403 also used for some other kind errors
//if error is not skewerror than nothing going to disturb over method**

++ (void)updateTimeSkew:(AmazonServiceRequest *)request withReponse:(AmazonServiceResponse *)response
{

    if (response.httpStatusCode == 403)
    {
        //Getting DateTime from Request
        NSString * requestDateTimeString = [NSString stringWithFormat:@"%@",request.urlRequest.allHTTPHeaderFields[@"Date"]];

        //Converting Datestring into Date Format
        NSDateFormatter * requestDateFormat= [[NSDateFormatter alloc] init];
        requestDateFormat.dateFormat = @"EEE, dd MMM yyyy HH:mm:ss z";
        requestDateFormat.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];

        //Assigning date from dateFormatter
        NSDate *requestDate =[requestDateFormat dateFromString:requestDateTimeString];

        //Converting Datestring into Date Format
        NSDateFormatter *serverTimeformat = [[NSDateFormatter alloc] init];
        serverTimeformat.dateFormat = @"EEE, dd MMM yyyy HH:mm:ss z";
        serverTimeformat.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];

        //Getting Date from amazon response
        NSString *responseDate = [NSString stringWithFormat:@"%@",response.responseHeader[@"Date"]];
        NSDate *serverTime = [requestDateFormat dateFromString:responseDate];

        //Calculating Time differnce
        NSTimeInterval time =  [requestDate timeIntervalSinceDate:serverTime];

        //Setting clockSkew
        [AmazonSDKUtil setRuntimeClockSkew:time];
    }
}