Error trying to set up user MFA Preferences - amazon-cognito

I'm using the AWS CLI to enable a MFA user pool with only TOTP MFA (no SMS).
aws cognito-idp set-user-pool-mfa-config --user-pool-id xxxx_xxxx --mfa-configuration OPTIONAL --software-token-mfa-configuration Enabled=true
{
"SoftwareTokenMfaConfiguration": {
"Enabled": true
},
"MfaConfiguration": "OPTIONAL"
}
Seems okay, right?
But when I try to set up an user preference I keep getting this error:
An error occurred (InvalidParameterException) when calling the AdminSetUserMFAPreference operation: User has not set up software token mfa
Command:
aws cognito-idp admin-set-user-mfa-preference --user-pool-id xxxx_xxxx --username username#email.com --software-token-mfa-settings Enabled=true
Tryin to use admin-set-user-preference also doesn't work:
aws cognito-idp admin-set-user-settings --user-pool-id us-xxxx-xxxx--username username#email.com --mfa-option DeliveryMedium=EMAIL
An error occurred (InvalidParameterException) when calling the AdminSetUserSettings operation: Only phone_number attribute is currently supported as a MFA option.
What am I missing? Does it need an extra configuration not mentioned anywhere in documentation?
Solution:
First you need to get the ACCESS_TOKEN for the user and proceed to start the TOTP process:
aws cognito-idp associate-software-token --access-token ACCESS_TOKEN
(this will generate a unique code that you could use in Google Authenticator)
With the TOTP code retrieved from the Authenticator app run:
aws cognito-idp verify-software-token --access-token ACCESS_TOKEN --user-code USER_CODE
With the successfull message from the previous command you can change the user preference:
aws cognito-idp admin-set-user-mfa-preference --user-pool-id xxxxx --username xxxxxxx --software-token-mfa-settings Enabled=True,PreferredMfa=True

Solution:
First you need to get the ACCESS_TOKEN for the user and proceed to start the TOTP process:
aws cognito-idp associate-software-token --access-token ACCESS_TOKEN
(this will generate a unique code that you could use in Google Authenticator)
With the TOTP code retrieved from the Authenticator app run:
aws cognito-idp verify-software-token --access-token ACCESS_TOKEN --user-code USER_CODE
With the successfull message from the previous command you can change the user preference:
aws cognito-idp admin-set-user-mfa-preference --user-pool-id xxxxx --username xxxxxxx --software-token-mfa-settings Enabled=True,PreferredMfa=True

To setup the TOTP for user you have to call the AWS Cognito APIs in the following order
Associate Software Token
Verify Software Token
Set User MFA Preference
The associate software token will give you an SecretCode which you will convert to a QR either so that user can scan it with an authenticator app. Then you will call the verify software token and pass it the code generated by the authenticator app. And finally you will enable the MFA by calling the set user preference API. And voila.

Related

when trying to add a cognito user getting an error about missing secret

I am following this tutorial (so i am a newbe)
i have set up my cognito user pool. (of course if the tutorial is 1 month old it is out of date)
now i am trying to a user via the CLI
aws cognito-idp sign-up \
--region us-east-1 \
--client-id <CLIENTID> \
--username randy#mydomain.com \
--password password
And I get the error
An error occurred (NotAuthorizedException) when calling the SignUp operation: Client is configured for secret but secret was not received
Not sure what to change.
Thanks for any help
You need to recreate cognito user Pool, uncheck "create secret" and add allowed domain 'http://localhost' if you are in local or add you domain. This work for me !

How can curl authenticate to Google Cloud based on local gcloud's CLI authentication?

My script uses a sequence of gcloud commands and of course gcloud is authenticated. I need to use curl to access GCP REST APIs that are not available to gcloud. I can do this by generating a JSON credentials file in the Cloud Console, but I'd rather not do that as a separate manual step.
[Edit: The answer is to replace the gcloud auth string in that curl command with gcloud auth print-access-token. See answer below.]
This is how I do it now, using a JSON file downloaded from the Console.
GOOGLE_APPLICATION_CREDENTIALS=credentials.json
curl -X POST -H "Authorization: Bearer \"$(gcloud auth application-default print-access-token)\"" \
-H "Content-Type: application/json; charset=utf-8" \
https://cloudresourcemanager.googleapis.com/v1/projects/<MY_PROJECT>:getAncestry
Without that downloaded JSON, I get this:
ERROR: (gcloud.auth.application-default.print-access-token)
The Application Default Credentials are not available. They are available if running in Google Compute Engine.
Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing
to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials
for more information.
{ "error": {
"code": 401,
"message": "Request had invalid authentication credentials.
Expected OAuth 2 access token, login cookie or other valid authentication credential.
See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
}
How can I leverage my gcloud authentication to use curl? I don't mind using the JSON if I can automate its generation as part of this script. For example, is there a way to call gcloud to generate this JSON, which I would then set as GOOGLE_APPLICATION_CREDENTIALS?
Once you have the Cloud SDK authenticated, you can use the gcloud auth print-access-token command to get an access token for the current active account, without the need of specifying the path to the JSON credentials file.
You will still need the credentials.json file, if you wish to activate a service account for the Cloud SDK instance. However, I am pretty sure you will only have to do that once.
EDIT:
I noticed you are using the gcloud auth application-default print-access-token.
Keep in mind that, contrary to the gcloud auth print-access-token command, it uses the current Application Default Credential (ADC), which has to be set by specifying the credentials.json file path with the GOOGLE_APPLICATION_CREDENTIALS env variable, or by using the gcloud auth application-default login command.

How do I reset a Cognito user's password that has expired?

We're using Cognito. All is well. I added a user using the AdminCreateUser API, and they received their temporary password. Unfortunately they waited over a month to login, and now when they try to login with their temporary password, Cognito returns this error:
User account has expired, it must be reset by an administrator.
How do I do that? I don't see any reset button in the Cognito UI. Is there a CLI or API that I can call?
The commands admin-reset-user-password and admin-enable-user do not work for an expired user.
The way you reset an expired user is to call admin-create-user again with the parameter MessageAction value = 'RESEND'
For example via CLI command:
aws cognito-idp admin-create-user --region us-east-1 --user-pool-id us-east-1_youruserpoolid --username theusername --message-action RESEND
From the documentation:
"Set to 'RESEND' to resend the invitation message to a user that
already exists and reset the expiration limit on the user's account."
Once you have reset the user, the user will need to change the temporary password otherwise they will be put back into this state again once they have exceeded the expiration time period (by default 7 days according to AWS documentation).

Request had invalid authentication credentials. Expected OAuth 2 access token error in cloud speech api

i have followed the google cloud speech api quickstart of requesting api by using
curl -s -H "Content-Type: application/json" \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
https://speech.googleapis.com/v1/speech:recognize \
-d #sync-request.json
and following link but i got error of
{
"error": {
"code": 401,
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
}
What should i do now?
Thanx in advance
It could be that The Application Default Credentials are not available
Try to login by running
gcloud auth application-default login
And follow the instructions, reference: gcloud auth application-default login
If you want to make sure the authentication process went well, run:
gcloud auth application-default print-access-token
You should see an access token, reference gcloud auth application-default print-access-token
I fixed the problem by logging out, and logging in to agree to some new terms and conditions google have made since last time I used google clouds (firebase in my case).
Replace $(gcloud auth application-default print-access-token) with what gets printed when you call the command.
Make sure your date and time are correct and also your timezone is correct.
This was how I solved this problem
There is possibility that you have disabled auth. So
gcloud config set auth/disable_credentials false
Samir's solution worked for me.
Just a reminder that if using other software interacting with GCP, you may have to restart software before the auth takes effect.
In my case, when using RStudio, I ran gcloud auth application-default login to authenticate, then command + shift + f10 to restart the R session, and then everything was good to go.
Some packages will have a function that refreshes the token in the current R session. For example the bigrquery library has bq_auth() which adds the new token to the R session (without needing to restart the session etc)
If you have changed the scopes assigned to the credentials since the last time you signed-in your client, make sure you sign in again to update the client tokens.
I had this error when using GCP CLI, so unrelated but maybe someone stumbles on this thread same as me.
I ran this command:
gcloud auth application-default login
after that, the error was still there, but then I ran second command
gcloud auth application-default print-access-token
CLI then prompted me to provide password, I did, and after that I was able to use GCP CLI again (I didn't use access token that was returned, simply re-entering password worked for me)

Authorize Azure AD application to access RateCard API

Since a change in the Azure OAuth 2, I've an error:
The client 'xxx' with object id 'xxx' does not have authorization to perform action 'Microsoft.Commerce/RateCard/read' over scope '/subscriptions/xxx'.
I've followed the role-based assignment instructions, added a Reader role for my application to the DefaultResourceGroupResource.
I've also added an Admin role in the appRoles section of my application manifest.
And adding all possible app permissions :
To call the RateCard API, I retrieve a token :
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" "https://login.windows.net/xxx.onmicrosoft.com/oauth2/token" -d "grant_type=client_credentials&client_id=xxx&client_secret=xxx"
And I use it in my request :
curl -H "Authorization: Bearer <token>" "https://management.azure.com/subscriptions/xxxproviders/Microsoft.Commerce/RateCard?api-version=2015-06-01-preview&$filter=OfferDurableId eq 'MS-AZR-0003P' and Currency eq 'USD' and Locale eq 'en-US' and RegionInfo eq 'US'"
But I still have this error.
What should I do to add this authorization to my application ?
Here some screenshot of my app permissions:
After a brief call with the Azure support, they tell me that this kind of permission can't be handled via the portal, it has to be done in PowerShell.
So I had to download a Windows 10 Virtual Machine to run :
Login to Azure account:
Login-AzureRmAccount
Add permission:
New-AzureRMRoleAssignment -ServicePrincipalName "<my-app-id>" -RoleDefinitionName "Reader" -Scope "/subscriptions/<my-subscription-id>"
To check if permissions are assigned correctly:
Get-AzurermRoleAssignment -ServicePrincipalName "<my-app-id>"
I've followed the role-based assignment instructions, added a Reader
role for my application to the DefaultResourceGroupResource.
Instead of giving Reader role permission on an individual resource group, try giving the same permission on the subscription level.
Another thing you could do is create a custom role in your subscription with following permissions:
Microsoft.Commerce/RateCard/read
Microsoft.Commerce/UsageAggregates/read
Then you can assign this custom role to your application.