Closed jmarshall9120 closed 4 months ago
The default auth mode on your API is "iam". Are you specifying "userPool" as the authMode on the client?
The only client code I see in the description is:
client.models.user.list()
If you haven't already tried, can you try this?
client.models.user.list({
authMode: "userPool"
})
https://docs.amplify.aws/react/build-a-backend/data/query-data/#:~:text=Troubleshooting,Troubleshoot%20unauthorized%20errors "Troubleshooting Troubleshoot unauthorized errors"
Also, in case I'm misunderstanding, and you actually do mean to use iam
as an auth mode for authenticated users, then the authorization rule you need on the schema is actually:
allow.authenticated("identityPool")
In the screenshot the request is being signed, which means IAM is being used as the authMode. The role being used is the AuthRole on your Cognito IdentityPool.
If you wanted to authorize using your Cognito UserPool, then the request would have a JWT access token in the Authorization header.
@chrisbonifacio - You maybe on to something. The original idea when I started testing this was to allow both guests & users. So in the mixing and matching process experimenting here I may have gotten my environment a little messed up. Let me ask a couple questions, that may seem off topic, but may help me here:
1).
So is it the recommended pattern, that when authenticating for users or guests we do something like this:
authUser = await getCurrentUser();
if (authUser?.userId){
client.models.user.list({
authMode: 'userPools'
})
} else {
client.models.user.list({
authMode: 'identityPool'
})
}
Because even though, the docs show this:
It seems from your comments and my testing that authMode:'identityPool'
does not actually allow signed in user access.
2).
Let me confirm the auth flow strategy with you so we don't confuse ourselves. Authenticated User: AWSCognitoIdentityProviderService.InitiateAuth --> JWT | AWSCognitoIdentityService.GetId --> IdentityId |
---|
AWSCognitoIdentityService.GetCredentialsForIdentity --> Credentials
Unauthenticated User (guest): AWSCognitoIdentityService.GetId --> IdentityId | AWSCognitoIdentityService.GetCredentialsForIdentity --> Credentials
For a guest appsync accepts credentials but for an authenticated user appsync only accepts JWT - even though the sign in flow goes through the trouble of obtaining the credentials for an authenticated user anyway?
Also, just retested to make sue I wasn't crazy, and noticed the authMode names in that screen shotted doc are wrong as well. There is no authMode 'userPools' - its 'userPool'.
So is it the recommended pattern, that when authenticating for users or guests we do something like this: ... It seems from your comments and my testing that authMode:'identityPool' does not actually allow signed in user access.
The identityPool
authMode allows both signed in and guest user access. The Amplify data client will use the AuthRole when signed in and UnAuthRole when signed out. With the logic you provided, the identityPool
authMode would be used if the auth rule on your schema is allow.guest()
, because if a user is not signed in the else statement will execute.
This would be aligned with your original idea to allow both guests & users.
Let me confirm the auth flow strategy with you so we don't confuse ourselves. Authenticated User: AWSCognitoIdentityProviderService.InitiateAuth --> JWT AWSCognitoIdentityService.GetId --> IdentityId AWSCognitoIdentityService.GetCredentialsForIdentity --> Credentials
Unauthenticated User (guest): AWSCognitoIdentityService.GetId --> IdentityId | AWSCognitoIdentityService.GetCredentialsForIdentity --> Credentials
For a guest appsync accepts credentials but for an authenticated user appsync only accepts JWT - even though the sign in flow goes through the trouble of obtaining the credentials for an authenticated user anyway?
That breakdown seems correct to me.
AppSync accepts Cognito access tokens or an OIDC token for authenticated users. However, AppSync also accepts IAM as an auth mode, Amplify just creates an IAM role (AuthRole) for "authenticated users" but through an identityPool. This might be a bit confusing because the user still has to be logged in for Amplify to use this role.
Also, just retested to make sue I wasn't crazy, and noticed the authMode names in that screen shotted doc are wrong as well. There is no authMode 'userPools' - its 'userPool'.
Thanks for pointing this out! Just opened a PR with a correction:
Hi 👋 Closing this as we have not heard back from you. If you are still experiencing this issue and in need of assistance, please feel free to comment and provide us with any information previously requested by our team members so we can re-open this issue and be better able to assist you.
Thank you!
Before opening, please confirm:
JavaScript Framework
Vue
Amplify APIs
Authentication, GraphQL API
Amplify Version
v6
Amplify Categories
auth, api
Backend
Amplify Gen 2 (Preview)
Environment information
Describe the bug
Disclaimer - Not 100% sure this is a bug yet, but I have enough info its time make a record.
API is not allowing authenticated users. Calls to the graphql endpoint in the sandbox, with an authenticated user result in:
Been following the tutorials here for Amplify Gen2: https://docs.amplify.aws/vue/build-a-backend/data/customize-authz/
Here's the setup:
In my app there's a login page, and a call to
getCurrentUser()
+client.models.user.list()
inApp.vue
. I don't think that code is important.The schema on the appsync backend query looks like this:
Here's the http request:
You can see that the cognito calls are made correctly for the sign in and the signature/session token are calculated for the request which should suggest that everything code wise from the amplify gen 2 developers perspective (my perspective) is correct. I've also confirmed this all in python using http only.
What have I tried:
My next stop is IAM at this point. My theory is that the sandbox / amplify gen 2 have not setup user pool roles correctly.
Expected behavior
Should allow the query to pass.
Reproduction steps
Hopefully if I find the smoking gun here, more reproduction examples can be give. If this seems un-reproducible I can share the repo. I assume because the issue has persisted on rebuild of the sandbox, and in a direct http request reproduction, that the issue must be in the building of the sandbox somewhere.
Code Snippet
Log output
aws-exports.js
No response
Manual configuration
No response
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
No response