Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Amazon S3 how to validate Access Key Id and Secret Access Key? PHP SDK v3

I'm trying to catch wrong secret key exception on registerStreamWrapper, and it is just not happening.

My problem is originated when trying to verify if object exists, if anyone call help me with this(best way to do it), would be awesome, but this is another issue. Back to the problem.

I'm using this code to check if object exists using registerStreamWrapper:

try{
        $s3Client = new \Aws\S3\S3Client($sharedConfig);
        $s3Client->registerStreamWrapper();
        $file = 's3://'."mybucket".'/'."testpath/testpic.jpg";

        if(file_exists($file)){
            echo "true";
        }else{
            echo "false";
        }

    } catch (S3Exception $e) {
        // Catch an S3 specific exception.
        echo $e->getMessage();
    } catch (AwsException $e) {
         // This catches the more generic AwsException. You can grab information
        // from the exception using methods of the exception object.
        echo $e->getAwsRequestId() . "\n";
        echo $e->getAwsErrorType() . "\n";
        echo $e->getAwsErrorCode() . "\n";
    }

If I provide wrong secret key, it just returns false. Is there anyway to validate access key id and secret access key? This would make my life so easy.

Can't find anything here : http://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html or here: http://docs.aws.amazon.com/aws-sdk-php/v3/guide/

like image 781
Lauro182 Avatar asked Aug 24 '15 20:08

Lauro182


2 Answers

Here is trick for AWS Command Line Interface (CLI). It is possible to validate them using next command:

aws iam get-account-authorization-details

Even if user does not have authorization to perform GetAccountAuthorizationDetails operation, if AWS Access Key is correct then you will get as output something like this:

An error occurred (AccessDenied) when calling the 
GetAccountAuthorizationDetails operation: 
User: arn:aws:iam::012345678901:user/username is not authorized to perform:
iam:GetAccountAuthorizationDetails

Which means that AWS not only has validated credentials, but also returned to you account ID and user name to which those credentials are linked to.

If Access Key ID is wrong, then you will get next reply: An error occurred (InvalidClientTokenId) when calling the GetAccountAuthorizatio nDetails operation: The security token included in the request is invalid.

Alternatively for some other services like S3, if you will try to execute 'aws s3 ls' it may say (InvalidAccessKeyId).

If Secret Access Key is wrong, then you will get next reply: An error occurred (SignatureDoesNotMatch) when calling the GetAccountAuthorizati onDetails operation: The request signature we calculated does not match the sign ature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

like image 115
Dmitriy Reznikov Avatar answered Oct 03 '22 07:10

Dmitriy Reznikov


I went to get help from the profesionals at the amazon's forums, and I kinda got an answer, there's no service to verify access key id and secret access key, you have to use some service that does throw exception(I didn't want to do this, but it is what you have to do), then catch the exception and handle it. I did the following function with listsBuckets, and since I'm using a service just to check if my access key id and secret are correct, I added checking if the bucket that I'm going to use exists:

function checkaccess($bucket){
global $sharedConfig;

try{
        $s3Client = new \Aws\S3\S3Client($sharedConfig);
        //Get buckets list
        $buckets = $s3Client->listBuckets([]);
        //Go through every bucket
        foreach ($buckets['Buckets'] as $key=>$obj){
            //Check if the bucket I'm going to use exists
            if ($buckets['Buckets'][$key]['Name'] === $bucket){
                //If exists, return true, everything is fine
                return true;
            }
        }
        //Bucket doesn't exists but access key id and secret are correct.
        return false;
    } catch (S3Exception $e) {
        //Exception ocurred, 
        //"SignatureDoesNotMatch" for bad secret access key
        //"InvalidAccessKeyId" for invalid access key id
        return ($e->getAwsErrorCode());
    } catch (AwsException $e) {
        //More generic exceptions
        error_log($e->getAwsRequestId());
        error_log($e->getAwsErrorType());
        error_log($e->getAwsErrorCode());
        return($e->getAwsErrorType());
    }
}

This way I can know if access key id and secret access key are valid, and if my buckets exists. You can skip the check for bucket if you want and return true if no exception occurs and false for exception if you want just to check for access key id and secret access key, but some other exception may occur.

Hopes this helps someone encountering the same problems as I did.

like image 43
Lauro182 Avatar answered Oct 03 '22 06:10

Lauro182