Can't authenticate to cognito from backend as administrator - javascript

I need to get all users from my backend (Node.js). But when I am trying to authenticate I've got:
error AccessDeniedException, User ... assumed-role/Cognito_XXXUnauth_Role/ CognitoIdentityCredentials is not authorized to perform: cognito-idp:AdminInitiateAuth ...
My current code:
let cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider()
var params = {
AuthFlow: 'ADMIN_NO_SRP_AUTH',
ClientId: process.env.AWS_CLIENT_ID,
UserPoolId: process.env.AWS_USER_POOL_ID,
AuthParameters: {
USERNAME: '...'
PASSWORD: '...'
}
}
cognitoidentityserviceprovider.adminInitiateAuth(params, (err, result) => { ... })
It looks like I didn't log in since Cognito_XXXUnath_Role is used. Anyone had similar problem?

You are trying to use a Cognito Federated Identity credentials providers to create the CognitoIdentityServiceProvider service client. This will make the AWS SDK to call the Federated Identity service to obtain temporary AWS credentials which will be used to call cognitoidentityserviceprovider.adminInitiateAuth(...).
In this case, there are two possible solutions:
Use a different credentials provider to create the CognitoIdentityServiceProvider client with credentials which have access to call adminInitiateAuth API. Since you care doing this from backend, it should be safe to do so. This guide can help you with this.
If you must use the Cognito Federated Unauth role to create the service client, allow cognito-idp:AdminInitiateAuth in the unauthenticated role of the identity pool you are using to do this.

In case you are using Serverless framework, then the following settings should fix an error:
provider:
# you can add statements to the Lambda function's IAM Role here
iamRoleStatements:
- Effect: "Allow"
Action:
- "cognito-idp:AdminInitiateAuth"
Resource:
- "arn:aws:cognito-idp:*"

Related

Amplify (JavaScript) - SAML login

I'm struggling for a few days now with AD SAML login in Amplify.
I've seen a few tutorials but my desired flow is different.
I don't have any button which will user click to trigger Auth sequence (and open popup).
Our users are going into a link:
https://....amazoncognito.com/login?response_type=token&client_id=...&redirect_uri=...
Which automatically redirect them into the front-end.
http://localhost:3000/#access_token=...&id_token=...&token_type=Bearer&expires_in=600
Which I can grab the access_token, id_token, token_type and expires_in from the query params.
I can do calls to our back-end with those tokens succesfully..
But what I am struggling with is make Amplify "login" sequence.. so it will identify the user and will create the localStorage values.. so for example when calling Auth.currentSession() it will return the token.
I've tried using Auth.federatedSignIn(..) but to no avail. I am not even sure if it's support this flow or not.
This is what I tried:
Auth.federatedSignIn(
'test-ad',
{
token: idToken,
expires_at: expiresIn,
},
{
name: "test-user",
},
);
But I keep getting
Unhandled Rejection (NotAuthorizedException): Invalid login token. Issuer doesn't match providerName
Which is strange as the providerName I'm passing ('test-ad') is the same as I configured in Cognito SAML Provider Name field (in Cognito -> User Pool -> Federation -> Identity Providers -> SAML -> new Provider)
I have my Amplify configured correctly
Amplify.configure({
Auth: {
identityPoolId: ...,
region: ...,
userPoolId: ...,
userPoolWebClientId: ...
}
});
And I can see the Chrome network call is with the correct payload:
{
"IdentityPoolId":"us-east-x:...",
"Logins":{
"test-ad":"...idToken..."
}
}
so - How can I authenticate into Amplify using token? is it even possible?
Any help will be appreciated!

How do I make authenticated requests to Amplify GraphQL using Firebase Auth as OIDC?

I need help setting up Firebase Auth + Amplify GraphQL. I'm trying to log in using federated sign with securetoken.google.com/PROJECT-ID as the provider, and it seems to log in alright because when I call Auth.currentAuthenticatedUser() I get the token, and when listening to Hub "signIn" event I get the token. My problem is making authenticated requests to my GraphQL API.
const signIn = async () => {
try {
// already logged in using firebase so I just need to get the token from the current user
const tokenResult = await currentUser?.getIdTokenResult()
await Auth.federatedSignIn('securetoken.google.com/PROJECT-ID', {
token: tokenResult?.token,
})
const res = await Auth.currentAuthenticatedUser()
console.log('token', res.token) // eyjhxxxxxxxxxx...
} catch (error) {
// ...
}
}
const client = new AWSAppSyncClient({
url: AppSyncConfig.aws_appsync_graphqlEndpoint,
region: AppSyncConfig.aws_appsync_region,
auth: {
type: AppSyncConfig.aws_appsync_authenticationType,
jwtToken: () => getToken(),
},
})
const getToken = async () => {
const token = await Cache.getItem('#accessToken')
return token
}
When calling Auth.currentSession() I get "No current user". Also, I do see the token in the Authorization header when I attempt to fetch data.
I have had a similar issue so here are some things you can have a look at.
In the Appsync in the AWS Console
https://eu-west-1.console.aws.amazon.com/appsync/home
Make sure that your primary authorization mode is set to Open Id Connect, or add another authorization provider specifying "OpenId Connect" if you are happy with the primary.
If that does not solve it, you can try to add the #aws_oidc AppSync directive to your GraphQL schema.
type Query {
getPosts:[Post!]! #aws_oidc
}
or
type Post
#model
#auth(
rules: [
{ allow: owner, provider: oidc }
...
more here: https://aws.amazon.com/blogs/mobile/graphql-security-appsync-amplify/
Lastly, if you have more than one authorization provider, you might have to switch the primary authorization provider to "OpenId Connect" - the issue I had was that Cognito (primary) blocked my secondary API Key authorization provider.
Update
AWS uses IAM roles for everything related to security. So when you authenticate with whichever authentication provider an IAM role will be assigned to that request, and that IAM role needs permission on the resource in question, like execute permission on GraphQL queries, scanning of DynamoDB tables etc. as per this image:
So you might need specific rules set in the IAM console for the IAM role in question - or at least check that it has permission - if not, you'll also get an unauthorized error message in the Appsync GraphQL query console.
more here: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WIF.html?icmpid=docs_ddb_console
and here: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/specifying-conditions.html?icmpid=docs_ddb_console
Try removing the cookie storage configuration in aws-exports.js may solve it. Maybe this helps you.
More discussion here Link-1 and Link-2

How to configure Amazon AssumeRoleWithWebIdentity for access token in Ionic 3 project?

I'm little bit confuse using AssumeRoleWithWebIdentity method.
let me describe step by step.
Step 1:-I get the facebook token from facebook.
Step 2:-using getId method, I get the IdentityId from amzon cognito.
Step 3:-used getOpenIdToken and passed the IdentityId I get the {IdentityId,Token} in response.
(Question 1: Can I access the amazon services using this token?)
Step 4:- Then I'm trying to implement AssumeRoleWithWebIdentity method
using the params:-
params = {
RoleArn: arn:aws:iam::XXXXX:role/XXXXX,
RoleSessionName: 'XXXX',
WebIdentityToken: 'XXXX'
DurationSeconds: 3600,
ProviderId: 'www.amazon.com'
};
let sts = new AWS.STS();
sts.assumeRoleWithWebIdentity(params, function (err, data) {
if (err) console.log(err, err.stack);
else console.log(data);
})
Question 2:-WebIdentityToken ,I have to use which one the provided by the facebook or by the cognito in return of getOpenIdToken method.
Question 3:- ProviderId, I am trying to logged in using facebook is it will be graph.facebook.com or www.amazon.com?
Question 4: When I am using WebIdentityToken as provide by getOpenIdToken in response and ProviderId as www.amazon.com I'm getting InvalidIdentityToken: Provided Token is not a Login With Amazon token
Question 5:- When I am using WebIdentityToken as provide by facebook and ProviderId as graph.facebook.com I'm getting AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentity
If it's right how to give access please tell step by step
Your end goal seems to be to obtain temporary AWS credentials for your app users. You do not need to interact with AssumeRoleWithWebIdentity for this. Amazon Cognito Federated Identities directly vends AWS credentials and hides all the STS interactions.
As explained in authentication flow documentation, you need to interact with GetId and GetCredentialsForIdentity APIs and your app user will directly get temporary AWS credentials.
As for answer to your Question 3, no the OpenId token vended by GetOpenIdToken cannot be used with AWS APIs directly. For detailed explanation, you can refer to this answer.

How to delete amazon cognito user?

I want to delete cognito user using my nodejs application.
Example
cognitoUser.deleteUser (err, result) ->
if err
reject err
resolve result
when i try to delete cognito user error throws as follows
Error: User is not authenticated
cognitoUser.deleteUser is used by an authenticated user to delete himself but i want to delete all users using super user
Please give me some idea to solve this problem.
You can use the main aws javascript SDK and call the adminDeleteUser operation. It is an authenticated operation and it will require developer credentials for you to call it.
https://github.com/aws/aws-sdk-js/blob/master/apis/cognito-idp-2016-04-18.normal.json#L100
var aws = require('aws-sdk');
var CognitoIdentityServiceProvider = aws.CognitoIdentityServiceProvider;
var client = new CognitoIdentityServiceProvider({ apiVersion: '2016-04-19', region: 'us-east-1' });
//now you can call adminDeleteUser on the client object
You can do from AWS-CLI
aws cognito-idp admin-delete-user --user-pool-id ${user pool id} --username ${username usually email here}

API Gateway authentication with Cognito Federated Identities

I want to use Cognito Federated Entity (allowing signin through Google etc), to allow access to API Gateway for a web javascript application.
I managed to get the Cognito's sessionToken through signing-in with Google but I'm stuck on the API Gateway configuration for enabling the session token.
Is there a good tutorial for this entire Federated Entity authentication workflow?
Thanks!
Since you want to invoke APIs via authenticated Cognito identity, first
Amend the auth role of the identitypool to have api execute policy, you could just attach the managed policy "AmazonAPIGatewayInvokeFullAccess" to the respective role
In API gateway under respective method request, add Authorization as
"AWS_IAM"
You need to sign the request while using "IAM" auth, explained here https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html
Instead of #3, you could generate and download the SDK from the stage panel of your API gateway, and make a call to the api via sdk.
Once you obtain the cognito session, you could make a call using the sdk like below
var apigClient = apigClientFactory.newClient({
accessKey: AWSCognito.config.credentials.accessKeyId,
secretKey: AWSCognito.config.credentials.secretAccessKey,
sessionToken: AWSCognito.config.credentials.sessionToken
});
var params = {
// This is where any modeled request parameters should be added.
// The key is the parameter name, as it is defined in the API in API Gateway.
};
var body = {};
var additionalParams = {
// If there are any unmodeled query parameters or headers that must be
// sent with the request, add them here.
headers: {
'Content-Type': 'application/json'
},
queryParams: {}
};
apigClient.<resource><Method>(params, body, additionalParams)
.then(function(result) {
//
}).catch(function(err) {
//
});

Categories