Get AWS IAM credentials from PHP SDK - php

I use AWS Services regularly and have my PHP SDK automatically retrieve credentials from my ec2 instance when I connect with Amazon.
I now have a library that I want to use which also requires my AWS secret key and access key to be included when I instantiate the class.
How can I retrieve the current access token and secret key through the AWS PHP SDK so I don't hard code keys into my application?

Where are you storing your AWS Credentials? In a credentials file or IAM Role?
[EDIT after the OP provided specific use case details]
From the link that you provided modify the example to look like this. Note: I have not tested the code, but this will be close:
// Require Composer's autoloader
require_once __DIR__ . "/vendor/autoload.php";
use Aws\Credentials\Credentials
use Aws\Credentials\CredentialProvider;
use Aws\Exception\CredentialsException;
use EddTurtle\DirectUpload\Signature;
// Use the default credential provider
$provider = CredentialProvider::defaultProvider();
$credentials = $provider()->wait();
$upload = new Signature(
$credentials->getAccessKeyId(),
$credentials->getSecretKey(),
"YOUR_S3_BUCKET",
"eu-west-1"
);
[END EDIT]
The simplest answer if you are using a credentials file is to open ~/.aws/credentials in a text editor and extract them. Otherwise follow the details below.
See the bottom for the actual answer on how to extract your access key once you have them loaded.
The following example will create a DynamoDB client using credentials stored in ~/.aws/credentials (normally created by the AWS CLI) from the profile named 'project1':
$client = new DynamoDbClient([
'profile' => 'project1',
'region' => 'us-west-2',
'version' => 'latest'
]);
However, usually you will want the SDK to locate your credentials automatically. The AWS SDK will search for your credentials in the following order (not all cases included):
Environment Variables (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, etc.)
In the default profile section of ~/.aws/credentials
EC2 IAM Role
Normally just use this example and let the SDK find the credentials for you:
use Aws\Credentials\CredentialProvider;
use Aws\S3\S3Client;
// Use the default credential provider
$provider = CredentialProvider::defaultProvider();
// Pass the provider to the client
$client = new S3Client([
'region' => 'us-west-2',
'version' => '2006-03-01',
'credentials' => $provider
]);
The SDK has a number of credential providers so that you can control exactly where your credentials are coming from.
PHP Class CredentialProvider
One item is that you mention Access Token. This means that you are using STS Assume Role type of access. The PHP SDK supports this also. Just dig into the documentation for STS:
PHP STS Client
Once you have loaded your credentials into a provider you can use the class Credentials to extract the three components (AccessKeyId, AcessKeySecret, SecurityToken):
PHP Class Credentials

Related

How to create a credential (for google sheets) on GCE with php code?

I put my php code in GCE and wanna to modify google sheets.
Google told me that i don't have to apply a extra credential by using GCP>API because there's a strategy called Application Default Credentials (ADC) will find application's credentials.
I first check the environment variable "GOOGLE_APPLICATION_CREDENTIALS" in GCE server but it's empty.
Then i follow this tutorial https://cloud.google.com/docs/authentication/production?hl=zh_TW#auth-cloud-implicit-php and install this:
composer require google/cloud-storage
I tried the code under and got some error.
namespace Google\Cloud\Samples\Auth;
// Imports GCECredentials and the Cloud Storage client library.
use Google\Auth\Credentials\GCECredentials;
use Google\Cloud\Storage\StorageClient;
function auth_cloud_explicit_compute_engine($projectId)
{
$gceCredentials = new GCECredentials();
$config = [
'projectId' => $projectId,
'credentialsFetcher' => $gceCredentials,
];
$storage = new StorageClient($config);
# Make an authenticated API request (listing storage buckets)
foreach ($storage->buckets() as $bucket) {
printf('Bucket: %s' . PHP_EOL, $bucket->name());
}
}
PHP Fatal error: Uncaught Error: Class 'GCECredentials' not found in /var/www/html/google_sheets/t2.php:5
More question:
Will this code create a json file as credential for me to access google sheets?
$gceCredentials = new GCECredentials();
Or where can i find the service account key??
Please tell me what should i do, thanks a lot.

Access aws services without key & secret in php

To be clear, We have created the EC2 policy, so my site can directly access the services like Parameter store, S3, Amazon SES etc.
As of now, all of my credentials are stored on AWS Parameter Store and then site is using those credentials i.e. DB credentials, diff. API keys etc. So only hard coded credentials are the one which fetch the parameters from Parameter Store. Now client want to remove those hard coded credentials as well, that's why we have created the EC2 Policy.
Till now, we have code like below to fetch the parameters:
$config = array(
'version' => 'latest',
'region' => '*****',
'credentials' => array(
'key' => '*******',
'secret' => '******',
)
);
$s3_instance = new \Aws\Ssm\SsmClient($config);
$result = $s3_instance->getParameters([
'Names' => $credential_group,
'WithDecryption' => true
]);
//converting S3 private data to array to read
$keys = $result->toArray();
var_dump($keys);
Now the question is what i have to change in above code, so it should work without passing those credentials.
Note: I am using AWS PHP library to perform above.
Update
Further reading the documentation, https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html
Using Credentials from Environment Variables
If you don't provide credentials to a client object at the time of its instantiation, the SDK attempts to find credentials in your environment. The first place the SDK checks for credentials is in your environment variables. The SDK uses the getenv() function function to look for the AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN environment variables. These credentials are referred to as environment credentials.
So after that, i have tried the below:
var_dump(getenv('AWS_ACCESS_KEY_ID'));
But it returns the bool(false). So does i need to manually setup those in environment credentials?
Which things i need to change in above code?
Update
Based on this doc: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_configuration.html#credentials
I had made below change (Removed the credentials part from array):
$config = array(
'version' => 'latest',
'region' => '*****'
);
Then system throws the below warnings:
Warning: include(Test_Role_Cognitoaccess_from_instanceRole.php): failed to open stream
Warning: include(): Failed opening 'Test_Role_Cognitoaccess_from_instanceRole.php' for inclusion (include_path='.:/usr/share/pear:/usr/share/php')
Warning: include(Test_Role_Cognitoaccess_from_instanceRole.php): failed to open stream
Warning: include(): Failed opening 'Test_Role_Cognitoaccess_from_instanceRole.php' for inclusion (include_path='.:/usr/share/pear:/usr/share/php')
As you already mentioned that you attached the policy to EC2 IAM role to access other AWS services.
You should try to create a default credential provider, this will automatically pick keys from the role.
$provider = CredentialProvider::chain(CredentialProvider::env(), CredentialProvider::ini(), CredentialProvider::instanceProfile(), CredentialProvider::ecsCredentials());
When you pass credentials directly to SsmClient and same time you have defined a role to the EC2 machine then you are making confusion for the AWS. If you have defined the permission for the EC2 instance then just do as follow:
use Aws\Ssm\SsmClient;
$client = new SsmClient(['version' => 'latest', 'region' => 'ap-southeast-2']);
$result = $client->getParameters(['Names' => ['My-SECRATE-KEY'], 'WithDecryption' => true]);
print_r($result);
Please keep in mind that permissions take a little time to propagate and in this period you will get permission error for the specific user. If you wait and let the changes take effect then mentioned code will work without any error. In my case I attached AmazonSSMReadOnlyAccess to the EC2 role and to EC2 instance. If you key/value in Parameter store is not encrypted then you can remove 'WithDecryption' => true or change it to false.

Marketing Api Permission Exception

I need to get some automated ad insights using the Marketing Api. For this purpose I have created a System User via the Business Manager, and generated a System User access token with the ads_read permission.
Using this token then to make api calls and get a specific Campaign's Insights, with the FacebookAds php v2.6 sdk, I get the following error:
Uncaught exception 'FacebookAds\Http\Exception\PermissionException'
with message '(#275) Cannot determine the target object for this
request. Currently supported objects include ad account, business
account and associated objects.'
Does my app need to be whitelisted or am I missing something else? I noticed that next to the 'ads_read' permission there was this note that stated '(your App must be whitelisted)'.
Here is the sample code I'm using
<?php
define('VENDOR_DIR', 'vendor/'); // Path to the Vendor directory
$loader = require VENDOR_DIR.'autoload.php';
use FacebookAds\Api;
use FacebookAds\Object\Campaign;
// Initialize a new Session and instantiate an Api object
Api::init(
'xxxxxxxxxxxxxxxx', // App ID
'xxxxxxxxxxxxxxxxx',
'xxxxxxxxxxxxxxxxxx' // System User Access Token
);
$api = Api::instance();
use FacebookAds\Object\Values\InsightsLevels;
$campaign = new Campaign('xxxxxxxxxxxxx');
$params = array(
'level' => InsightsLevels::CAMPAIGN,
);
$async_job = $campaign->getInsightsAsync(array(), $params);
$async_job->read();
while (!$async_job->isComplete()) {
sleep(1);
$async_job->read();
}
$async_job->getResult();
?>
It seems like your app doesn't have ads_read permission. Here you can find more information on how to ask for it: https://developers.facebook.com/docs/marketing-api/access

Custom OAuth2 user database

I'm currently implementing OAuth2 in my website to keep an user logged in inside an Android app. I want to change the default OAuth2 user database to my own user database. Unfortunately I can't find out how to do that. It should be possible with overriding classes and without changing the code in the core library, but how to do it?
This is what I have in my server.php file:
// Autoloading (composer is preferred, but for this example let's just do this)
require_once('/src/OAuth2/Autoloader.php');
OAuth2\Autoloader::register();
$storage = new OAuth2\Storage\Pdo(array('dsn' => 'mysql:host=xxxx;dbname=xxxx', 'username' => 'xxxx', 'password' => 'xxxx'));
// Pass a storage object or array of storage objects to the OAuth2 server class
$server = new OAuth2\Server($storage);
// Add the "Password / User Credentials" grant type
$server->addGrantType(new OAuth2\GrantType\UserCredentials($storage));
So here I want to use to my own user table instead of the default oauth_users table. And because the passwords are salted I need to have a different password check too. I am using the BShaffer OAuth2 Library: https://github.com/bshaffer/oauth2-server-php
With this library it's easy to write custom code so you don't have to touch the core of this library.
For this problem you'll have to create a custom storage class that implements the UserCredentialsInterface. There are two methods in here which you need to implement yourself
public function checkUserCredentials()
public function getUserDetails()
Here you can implement your logic for checking user details and fetching user details.
After this you'll need to add this storage to the oAuth server like this:
$server = new OAuth2\Server($storage);
$userStorage = new YourCustomUserStorage();
$server->addStorage($userStorage, 'user_credentials');
You'll also need to pass this storage to any Grant type you're adding to the server, in your case it looks like this:
$server->addGrantType(new OAuth2\GrantType\UserCredentials($userStorage));

create new user IAM with aws php sdk and limit access of one bucket

i am using aws php sdk for creating bucket in S3
i want to create new user IAM using aws php sdk.. .and then i want to save userkey and acceskey. ..
I got the tutorial for limit the access to user,but not get any for creating new user.
is there any way to create new user?
Install AWS SDK - http://docs.aws.amazon.com/aws-sdk-php/guide/latest/installation.html
Create an Iam client however you like by supplying your AWS credentials. The easiest example to demonstrate is putting the credentials in the PHP file directly - See http://docs.aws.amazon.com/aws-sdk-php/guide/latest/credentials.html
Then this example will create a user
<?php
require 'vendor/autoload.php';
$iamClient = \Aws\Iam\IamClient::factory(
[
'credentials' => [
'key' => 'YOUR_ACCESS_KEY',
'secret' => 'YOUR_SECRET_KEY'
]
]
);
$result = $iamClient->createUser(
[
// UserName is required
'UserName' => 'carlton',
// Optional
'Path' => '/packager/dev/'
]
);
4.Check http://docs.aws.amazon.com/aws-sdk-php/latest/class-Aws.Iam.IamClient.html for all of the methods available on the $iamClient variable we created. A good IDE will provide code completion on $iamClient so you can see available methods that way.

Categories