Paws::CognitoIdp::GetUser returns "Invalid Access Token" - amazon-web-services

Summary:
I tried to obtain AWS Cognito User name (OAuth2 from Google) with Perl module Paws::CognitoIdp::GetUser but I failed the code:
my $GetUserResponse = $cognito_idp->GetUser(
AccessToken => 'MyTokenModelType',
);
with the error Invalid Access Token.
Environment
I am developing Web service with following environment:
AWS + EC2 + Ubuntu 20.04 + nginx 1.20.1 + Perl 5.30.0
Using Cognito with Google OAuth2.0
What I can do now
When you access my Web service, Sign In with Google button will appear. If you click it, you can run my Perl CGI script.
What I cannot do now
I want to obtain your Google user name and mail address, but I cannot.
What I did
I wrote the following code:
my $cognito_idp = Paws->service('CognitoIdp',
region => "ap-northeast-1",
max_attempts => 3,
);
my $GetUserResponse = $cognito_idp->GetUser(
AccessToken => 'MyTokenModelType',
);
my $uname = $GetUserResponse->Username;
Then...
When I access my Web service, it failed with the Software error:
Software error:
Invalid Access Token
Trace begun at /usr/local/share/perl/5.30.0/Paws/Net/JsonResponse.pm line 22
Paws::Net::JsonResponse::process('Paws::Net::JsonResponse=HASH(0x56495fb33d78)', 'Paws::CognitoIdp::GetUser=HASH(0x56495fb41fd0)', 'Paws::Net::APIResponse=HASH(0x56495fde6f38)') called at /usr/local/share/perl/5.30.0/Paws/Net/Caller.pm line 46
Paws::Net::Caller::caller_to_response('Paws::Net::Caller=HASH(0x56495da09a38)', 'Paws::CognitoIdp=HASH(0x56495e05da48)', 'Paws::CognitoIdp::GetUser=HASH(0x56495fb41fd0)', 'Paws::Net::APIResponse=HASH(0x56495fde6f38)') called at /usr/local/share/perl/5.30.0/Paws/Net/RetryCallerRole.pm line 19
Paws::Net::RetryCallerRole::do_call('Paws::Net::Caller=HASH(0x56495da09a38)', 'Paws::CognitoIdp=HASH(0x56495e05da48)', 'Paws::CognitoIdp::GetUser=HASH(0x56495fb41fd0)') called at /usr/local/share/perl/5.30.0/Paws/CognitoIdp.pm line 331
Paws::CognitoIdp::GetUser('Paws::CognitoIdp=HASH(0x56495e05da48)', 'AccessToken', 'MyTokenModelType') called at /DocumentRoot/index.cgi line 16
For help, please send mail to this site's webmaster, giving this error message and the time and date of the error.
Maybe...
I referred following to the documentation
Maybe 'MyTokenModelType' is just the placeholder and I should specify the correct code.
But I don't know how I can make it.
In addition, I want to know how can I obtain not only user name but also user email address.
(Additional Info 2021-11-12)
Thanks to the comment, I read the article:
How to generate access token for an AWS Cognito user?
and I hacked AWS CLI command but I have not got the answer yet.
I think I got to do $ aws connito-idp initiate-auth but I cannot find what arguments I should pass.
In the AWS => Cognito => Users and groups menu, I see the entry of a user of my Web app.
Username: google_??????????
Enabled: Enabled
Account status: EXTERNAL_PROVIDER
Email: (users_email)
I changed my code like this for the experiment to find what information my Web app has.
use Data::Dumper;
my $cognito_idp = Paws->service('CognitoIdp',
region => "ap-northeast-1",
max_attempts => 3,
);
# my $GetUserResponse = $cognito_idp->GetUser(
# AccessToken => 'MyTokenModelType',
# );
# my $uname = $GetUserResponse->Username;
print "Content-type: text/html\n\n\n";
print '<!DOCTYPE html>';
print '<html><pre>';
print Dumper $cognito_idp;
print '</pre></html>';
and I see the contents of $cognito_idp like this:
$VAR1 = bless( {
'_region_for_signature' => 'ap-northeast-1',
...
'credentials' => bless( {
...
'selected_provider' => bless( {
'expiration' => 1636712506,
'actual_creds' => {
'Type' => 'AWS-HMAC',
'SecretAccessKey' => '??????????????',
'Code' => 'Success',
'AccessKeyId' => '???????????????',
'LastUpdated' => '2021-11-12T03:54:16Z',
'Token' => '?????????????????????????????????????',
'Expiration' => '2021-11-12T10:21:46Z'
},
...
I hope I could get the information of the user from the data above.
My question is, how I can specify the MyTokenModelType value of the code:
my $GetUserResponse = $cognito_idp->GetUser(
AccessToken => 'MyTokenModelType',
);
Still I want your info.
Thanks again.

Related

Can't resend verification code through AWS Cognito API

I have an AWS Cognito User Pool where users are created through Cognito's API using the AdminCreateUser action, which works fine. This sends out a verification e-mail to the user, containing a temporary password. So far so good.
Now a user did not receive this verification e-mail, so I need to send it again, using the ResendConfirmationCode action. I am attempting to do that with the below PHP code.
$userPoolId = '[POOL_ID_HERE]';
$backendAppId = '[APP_ID_HERE]';
$clientSecret = '[SECRET_HERE]';
$username = '[UUID_HERE]';
$secretHash = base64_encode(hash_hmac('sha256', $username . $backendAppId, $clientSecret, true));
$cognitoIdp->resendConfirmationCode([
'ClientId' => $backendAppId,
'SecretHash' => $secretHash,
'Username' => $username,
]);
That gives me the following error:
Aws/CognitoIdentityProvider/Exception/CognitoIdentityProviderException
with message 'Error executing "ResendConfirmationCode" on
"https://cognito-idp.eu-central-1.amazonaws.com"; AWS HTTP error:
Client error: POST https://cognito-idp.eu-central-1.amazonaws.com
resulted in a 400 Bad Request response:
{"__type":"NotAuthorizedException","message":"Can't resend
confirmation code for this user"} NotAuthorizedException (client):
Can't resend confirmation code for this user -
{"__type":"NotAuthorizedException","message":"Can't resend
confirmation code for this user"}'
I am using the credentials of a user which has the following IAM permissions for the user pool:
cognito-idp:AdminDeleteUser
cognito-idp:AdminCreateUser
cognito-idp:AdminAddUserToGroup
cognito-idp:ResendConfirmationCode
If I test the permissions using the IAM Policy Simulator, it gives me the green light, saying that everything is OK. To my knowledge, the cognito-idp:ResendConfirmationCode action should be sufficient, as sending out the verification e-mail works fine when creating the user.
What am I doing wrong here? An alternative approach would be to invoke the AdminCreateUser action again, setting the MessageAction parameter to RESEND. This would force the verification e-mail to be resent for existing users, but I prefer using the ResendConfirmationCode action if I can get it to work.
Any ideas? Thanks!
I understand that you would like your web application end users to receive a confirmation code again if they do not get the confirmation code due to some reason after they sign-up, and I also understand that you are getting the "NotAuthorizedException" when you are trying to run the ResendConfirmationCode API call from your code that uses the PHP SDK.
The ResendConfirmationCode API call[1] can be used after the sign-up API call[2], and it is not a part of the AdminCreateUser Authentication flow, which is why the error is thrown. The AdminCreateUser API call changes the status of the new user to the "Force Change Password State", and neither the ResendConfirmationCode call or the ForgotPassword call can work after AdminCreateUser is used for creating a new user.
If you would like your end-users to get the confirmation code again, you could use the AdminCreateUser API call itself and set the "RESEND" flag in MessageAction in the PHP code. There would be no other way to send the verification message again in this particular use-case, as per my understanding of Amazon Cognito.
An example of the API call in PHP according to the official documentation is as follows[3]:
$result = $client->adminCreateUser([
'DesiredDeliveryMediums' => ['<string>', ...],
'ForceAliasCreation' => true || false,
'MessageAction' => 'RESEND|SUPPRESS',
'TemporaryPassword' => '<string>',
'UserAttributes' => [
[
'Name' => '<string>', // REQUIRED
'Value' => '<string>',
],
// ...
],
'UserPoolId' => '<string>', // REQUIRED
'Username' => '<string>', // REQUIRED
'ValidationData' => [
[
'Name' => '<string>', // REQUIRED
'Value' => '<string>',
],
// ...
],
]);
After using setting 'MessageAction' as 'RESEND', the end-users should be able to receive the verification message again on their end.
References
[1]. https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/resend-confirmation-code.html
[2]. https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/sign-up.html
[3]. https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-cognito-idp-2016-04-18.html#admincreateuser

How to add people to facebook ad account in business manager

I am trying to create ad account by following https://developers.facebook.com/docs/marketing-api/reference/ad-account. With the help of this code I could successfully create ad account but I want to add myself as people as well but not getting any way to do this.
My ad account creation parameters are like
$attachment = array(
'access_token' => $this->accessToken,
'name' => $associative_arr['name'],
'currency' => $associative_arr['currency'],
'timezone_id' => $associative_arr['timezone_id'],
'end_advertiser' => $this->businessAccount,
'media_agency' => 'NONE',
'partner' => 'NONE',
'user_role' => '1001'
);
and endpoint is
https://graph.facebook.com/v2.8/BUSINESS_ID/adaccount
I also tried updating ad account using following
https://developers.facebook.com/docs/marketing-api/aduser/v2.8
but no gain.
I am getting following error.
stdClass Object
(
[error] => stdClass Object
(
[message] => (#10) Application does not have permission for this action
[type] => OAuthException
[code] => 10
[fbtrace_id] => HyAJtY0OOMf
)
)
Can anyone give me suggestions how I can ad people to my ad account using curl or PHP SDK?
Besides getting the ads_management permission, what was your app's Marketing API access level? The default access level supports up to only 5 ad account access. If you've accessed more than that via the API, you won't be able to do that on more accounts unless you apply for higher level of access. You can manage your ad account list in your app dashboard.

Google Admin 403 Error with PHP

I have been searching and trying many different solutions to this error that I have found not only this site but others as well.
Currently I am trying to just get a list of users or a specific user details based on parameters set. In the long run I would like to create and modify users and groups.
I have images but am new to posting to this site and I am unable to publish them here. I can confirm the following:
I have enabled API for the domain
api_studentportal(at)domain.com is a super admin
The Admin SDK is enabled under the developers console
Under 'Manage API client access' I have added '474470900273-asrfjsg0m0ucsfadeit456sg518l1bqa.apps.googleusercontent.com' to 'admin.directory.group' and 'admin.directory.user'
My Code:
date_default_timezone_set('America/Los_Angeles');
session_start();
set_include_path(get_include_path() . PATH_SEPARATOR . 'google/composer/src');
require 'composer/vendor/autoload.php';
$keychain = json_decode(file_get_contents('Google.json'), true);
$service_account_name = $keychain['client_email']; //474470900273-asrfjsg0m0ucsfadeit456sg518l1bqa#developer.gserviceaccount.com
$private_key = $keychain['private_key'];
$client = new Google_Client();
$client->setApplicationName("SAMPLE");
$service = new Google_Service_Directory($client);
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/admin.directory.user', 'https://www.googleapis.com/auth/admin.directory.group'),
$private_key,
'notasecret',
'http://oauth.net/grant_type/jwt/1.0/bearer',
'api_studentportal#domain.com'
);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();
$service = new Google_Service_Directory($client);
// Print the first 10 users in the domain.
$optParams = array(
'domain' => 'domain.com',
'maxResults' => 10,
'orderBy' => 'familyName',
'viewType' => 'domain_public',
);
$results = $service->users->listUsers($optParams);
And then I get the following PHP error:
Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling GET https://www.googleapis.com/admin/directory/v1/users?domain=domain.com&maxResults=10&orderBy=familyName&viewType=domain_public: (403) Not Authorized to access this resource/api' in google/composer/src/Google/Http/REST.php:110 Stack trace: #0 google/composer/src/Google/Http/REST.php(62): Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request), Object(Google_Client)) #1 [internal function]: Google_Http_REST::doExecute(Object(Google_Client), Object(Google_Http_Request)) #2 google/composer/src/Google/Task/Runner.php(174): call_user_func_array(Array, Array) #3 google/composer/src/Google/Http/REST.php(46): Google_Task_Runner->run() #4 google/composer/src/Google/Client.php(593): Google_Http_REST::execute(Object(Google_Client), Object(Google_Http_Request)) #5 google/composer in google/composer/src/Google/Http/REST.php on line 110
It seems as if it was just the viewType optParam defined. 'viewType' => 'domain_public' is invalid. Once that was removed the query worked.

How to create a user with the Admin Directory api using the google-api-ruby-client?

I've been trying a few combinations but can't seem to come up with something that works. More information about the API I'm asking about can be found here https://developers.google.com/admin-sdk/directory/v1/reference/users/insert . I have a feeling I'm just not setting up the request correctly. The following bit of code is known to work. I use it to set up the client that is able to query all the users.
client = Google::APIClient.new(:application_name => "myapp", :version => "v0.0.0")
client.authorization = Signet::OAuth2::Client.new(
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => "https://www.googleapis.com/auth/admin.directory.user",
:issuer => issuer,
:signing_key => key,
:person => user + "#" + domain)
client.authorization.fetch_access_token!
api = client.discovered_api("admin", "directory_v1")
When I try to use the following code
parameters = Hash.new
parameters["password"] = "ThisIsAPassword"
parameters["primaryEmail"] = "tstacct2#" + domain
parameters["name"] = {"givenName" => "Test", "familyName" => "Account2"}
parameters[:api_method] = api.users.insert
response = client.execute(parameters)
I always get back the same error "code": 400, "message": "Invalid Given/Family Name: FamilyName"
I've observed a few things while looking into this particular API. If I print out the parameters for both the list and the insert functions e.g
puts "--- Users List ---"
puts api.users.list.parameters
puts "--- Users Insert ---"
puts api.users.insert.parameters
Only the List actually displays the parameters
--- Users List ---
customer
domain
maxResults
orderBy
pageToken
query
showDeleted
sortOrder
--- Users Insert ---
This leaves me wondering if the ruby client is unable to retrieve the api and therefore unable to submit the request correctly or if I'm just doing something completely wrong.
I'd appreciate any idea's or direction that might help set me on the right path.
Thank you,
James
You need to supply an Users resource in the request body, which is also the reason why you don't see it in the params.
So the request should look like:
# code dealing with client and auth
api = client.discovered_api("admin", "directory_v1")
new_user = api.users.insert.request_schema.new({
'password' => 'aPassword',
'primaryEmail' => 'testAccount#myDomain.mygbiz.com',
'name' => {
'familyName' => 'John',
'givenName' => 'Doe'
}
})
result = client.execute(
:api_method => api.users.insert,
:body_object => new_user
)

SignatureDoesNotMatch in Amazon API

I am using the Amazon API and get this error while updating my stock from my database to Amazon website:
Caught Exception: Internal Error
Response Status Code: 0
Error Code:
Error Type:
Request ID:
XML:
I read this thread (amazonsellercommunity . com/forums/thread.jspa?messageID=2194823) and then get the error explanation:
<Error><Type>Sender</Type><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.</Message><Detail/></Error>
So I thought my MARKETPLACE_ID, MERCHANT_ID, AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY could be wrong. But I checked and these informations are correct.
Actually, I don't understand why this error happens... Before, it worked perfectly and since a couple of days it just crash. And I don't change anything in my code. Strange, isn't it?
Edit :
Here is my section code for signature.
define ('DATE_FORMAT', 'Y-m-d\TH:i:s\Z');
define('AWS_ACCESS_KEY_ID', 'ABC...'); // My AWS Access Key Id (20 characters)
define('AWS_SECRET_ACCESS_KEY', 'ABCDEF...'); // My AWS Secret Access Key (40 characters)
define('APPLICATION_NAME', 'MyCompany_AmazonMWS');
define('APPLICATION_VERSION', '0.0.1');
define ('MERCHANT_ID', 'XXXXXXX'); // My Merchant ID
define ('MARKETPLACE_ID', 'XXXXXXX'); // My Marketplace ID
$config = array (
'ServiceURL' => "https://mws.amazonservices.fr",
'ProxyHost' => null,
'ProxyPort' => -1,
'MaxErrorRetry' => 3,
);
$service = new MarketplaceWebService_Client(
AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY,
$config,
APPLICATION_NAME,
APPLICATION_VERSION
);
$parameters = array (
'Marketplace' => MARKETPLACE_ID,
'Merchant' => MERCHANT_ID,
'FeedType' => '_POST_INVENTORY_AVAILABILITY_DATA_',
'FeedContent' => $feedHandle,
'PurgeAndReplace' => false,
'ContentMd5' => base64_encode(md5(stream_get_contents($feedHandle), true)),
);
// and then I do this:
$request = new MarketplaceWebService_Model_SubmitFeedRequest($parameters);
invokeSubmitFeed($service, $request);
If you want to see some parts of my code, just ask.
If I recall correctly, the authentication mechanism for Amazon APIs is sensitive to the current date/time on your machine (which is used in the process of signing the request). Check to see if your date/time is set correctly.
For me it was just an error with my web app passing url escaped strings. The special characters weren't like by amazon and this (not so useful) error came up. Make sure your file names have no url escaped characters.
I solved it (on Ubuntu 14.04 Server) using ntpdate:
First make sure it is installed:
apt-get install ntpdate
And then execute:
ntpdate ntp.ubuntu.com