Amplify-cli: Updating API to add additional provider does not work

Created on 24 Jan 2020  路  8Comments  路  Source: aws-amplify/amplify-cli

Note: If your issue/bug is regarding the AWS Amplify Console service, please log it in the
Amplify Console GitHub Issue Tracker

Describe the bug
I'm trying to leverage multi auth so that I can have both public and authenticated access. Specifically, one mutation able to be performed by unaunthenticated, public users and the rest of the API restricted to authenticated users.

Amplify CLI Version
4.13.0

To Reproduce

  1. Set up auth (e.g. amplify add auth) using Cognito
 What do you want to do? Walkthrough all the auth configurations
 Select the authentication/authorization services that you want to use: User Sign-Up, Sign-In, connected with AWS IAM controls (Enables per-user Storage features for images or other content, Analytics, and more)
  Allow unauthenticated logins? (Provides scoped down permissions that you can control via AWS IAM) Yes
  Do you want to enable 3rd party authentication providers in your identity pool? No
  Do you want to add User Pool Groups? No
  Do you want to add an admin queries API? No
  Multifactor authentication (MFA) user login options: OFF
  Email based user registration/forgot password: Enabled (Requires per-user email entry at registration)
  Please specify an email verification subject: Your verification code
  Please specify an email verification message: Your verification code is {####}
  Do you want to override the default password policy for this User Pool? No
  Specify the app's refresh token expiration period (in days): 30
  Do you want to specify the user attributes this app can read and write? No
  Do you want to enable any of the following capabilities? (Press <space> to select, <a> to toggle all, i to invert selection)
  Do you want to use an OAuth flow? No
 Do you want to configure Lambda Triggers for Cognito? No
  1. Set up API (e.g. amplify add api) with Cognito as default

    ? Please select from one of the below mentioned services: GraphQL
    ? Choose the default authorization type for the API Amazon Cognito User Pool
    Use a Cognito user pool configured as a part of this project.
    ? Do you want to configure advanced settings for the GraphQL API Yes, I want to make some additional changes.
    ? Configure additional auth types? Yes
    ? Choose the additional authorization types you want to configure for the API (Press to select, a to toggle all, i to invert selection)
    ?Configure conflict detection? No

  2. Additional providers did not work.

    a) Additional providers not added to backend-config.json:

    {
        "hosting": {
        "S3AndCloudFront": {
            "service": "S3AndCloudFront",
            "providerPlugin": "awscloudformation"
        }
    },
    "auth": {
        "elasticpay7a0087987a008798": {
            "service": "Cognito",
            "providerPlugin": "awscloudformation",
            "dependsOn": []
        }
    },
    "api": {
        "elasticpay": {
            "service": "AppSync",
            "providerPlugin": "awscloudformation",
            "output": {
                "authConfig": {
                    "additionalAuthenticationProviders": [],
                    "defaultAuthentication": {
                        "authenticationType": "AMAZON_COGNITO_USER_POOLS",
                        "userPoolConfig": {
                            "userPoolId": "*****"
                        }
                    }
                }
            }
        }
    }
    }
    

    b) After pushing, the appsync shows no additional providers configured (see screenshot)
    c) Trying to add {allow: public, provider: iam, queries: null, mutations: [create]},, results in @auth directive with 'iam' provider found, but the project has no IAM authentication provider configured.

Expected behavior

1) Additional providers configured
2) I can set IAM as provider for a public @auth
3) I can perform API operations so long as I have an IAM policy that allows this

Screenshots
Screen Shot 2020-01-23 at 9 22 06 PM

Desktop (please complete the following information):

  • Mac
  • Node Version: v12.3.1

Additional context

  • Theoretically, why do I need to add another provider for public if I've enabled guest/unauthenticated users (w/ the respective IAM unauth role) via cognito?
  • The docs for public access are a bit all over the place :/ tried reading a bunch of issues and am still quite confused.
  • I manually added an additional provider via the AWS console to the AppSync API. After pulling with amplify, it did not update to include that one and attempting to push with "additionalAuthenticationProviders": [], showed no changes. Not sure why there's no delta between the state in the console and the code locally.
graphql-transformer pending-triage

Most helpful comment

hey @Audace,

2. Set up API (e.g. `amplify add api`) with Cognito as default
    ? Please select from one of the below mentioned services: GraphQL
    ? Choose the default authorization type for the API Amazon Cognito User Pool
    Use a Cognito user pool configured as a part of this project.
    ? Do you want to configure advanced settings for the GraphQL API Yes, I want to make some additional changes.
    ? Configure additional auth types? Yes
    ? Choose the additional authorization types you want to configure for the API (Press  to select, a to toggle all, i to invert selection)
    ?Configure conflict detection? No

I wanted to confirm with you for Choose the additional authorization types you want to configure for the API (Press to select, a to toggle all, i to invert selection) did you select IAM and the press <space> before pressing enter? From the the transcript you posted, it looks like IAM was not selected.

All 8 comments

Any updates here? I'm close to giving up on Amplify. I've followed various issue threads as well as the docs. It makes no sense that changing the settings via the CLI would not mutate the backend-config.json.

If I execute this code block:

  const currCreds = await Auth.currentCredentials();
  console.log(currCreds)

I see this returned:

CognitoIdentityCredentials {expired: false, expireTime: Fri Jan 24 2020 22:18:39 GMT-0500 (Eastern Standard Time), refreshCallbacks: Array(0), accessKeyId: "****", sessionToken: "****", 鈥
identityId: (...)
expired: false
expireTime: Fri Jan 24 2020 22:18:39 GMT-0500 (Eastern Standard Time) {}
refreshCallbacks: []
accessKeyId: "****"
sessionToken: "****"
params: {IdentityPoolId: "us-east-1:****", IdentityId: "us-east-1:****", RoleSessionName: "web-identity"}
data: {IdentityId: "us-east-1:****", Credentials: {鈥}
_identityId: "us-east-1:****"
_clientConfig: {region: "us-east-1"}
webIdentityCredentials: WebIdentityCredentials {expired: true, expireTime: null, refreshCallbacks: Array(0), accessKeyId: undefined, sessionToken: undefined, 鈥
cognito: features.constructor {config: Config, isGlobalEndpoint: false, endpoint: Endpoint, _events: {鈥, MONITOR_EVENTS_BUBBLE: 茠, 鈥
sts: features.constructor {config: Config, isGlobalEndpoint: true, endpoint: Endpoint, _events: {鈥, MONITOR_EVENTS_BUBBLE: 茠, 鈥
authenticated: false
secretAccessKey: "****"
get identityId: 茠 ()
set identityId: 茠 (identityId)
__proto__: Credentials

However, when I try to execute a query or mutation with the API, I get the following:

Uncaught (in promise) No current user

If I manually edit aws-exports.js and change aws_appsync_authenticationType from AMAZON_COGNITO_USER_POOLS to AWS_IAM, I now get a 401 when trying to execute a query or mutation. The 401 makes sense as I haven't edited the IAM policy for the unauthenticated users. However, in a production environment am I supposed to dynamically set the authenticationType of the entire app based on whether a user is authenticated or not? Seems a bit unideal.

I'm a bit back to square one, insofar as I need to update the directive for the type by adding @auth(rules: [{allow: public, provider: iam}]) in order to access the mutation through the console AppSync query client or through the JS API. Any attempt to change this and run amplify push results in @auth directive with 'iam' provider found, but the project has no IAM authentication provider configured.. This is despite having enabled unauthorized users in cognito, seeing an additional provider for AppSync API in the console, and having edited the role defined for the unauthorized user.

If I manually edit aws-exports.js and change aws_appsync_authenticationType from AMAZON_COGNITO_USER_POOLS to AWS_IAM, I now get a 401 when trying to execute a query or mutation. The 401 makes sense as I haven't edited the IAM policy for the unauthenticated users. However, in a production environment am I supposed to dynamically set the authenticationType of the entire app based on whether a user is authenticated or not? Seems a bit unideal.

For those who are reading this in the future, I found that the better approach to this is to change the auth type in the context of a single API call:

    const newObj = await API.graphql({
      query: mutations.createObj,
      variables: {input: {...},
      authMode: GRAPHQL_AUTH_MODE.AWS_IAM,
    });

This allows you to keep the default as defined in aws-exports.js. However, until the CLI lets you add additional providers / respects additional auth providers, it's all a bit for nought.

Ok, I finally (somehow) got past this.

  1. Manually edited backend-config.json to add this:
"additionalAuthenticationProviders": [
      {
          "authenticationType": "AWS_IAM"
      }
]
  1. Manually did the same to amplify-meta.json
  2. Changed transform.conf.json to use version 4

The CLI _finally_ picked up changes and added IAM as an additional provider. I was then able to add the directive to the type defined in the schema file. My hunch is that version 5 is somehow corrupted. The only reason I changed to version 4 was after sifting through public repos with similar configurations to what I wanted and noticed they were all on version 4 in that file. Wow - this was a bloody rabbit hole.

hey @Audace,

2. Set up API (e.g. `amplify add api`) with Cognito as default
    ? Please select from one of the below mentioned services: GraphQL
    ? Choose the default authorization type for the API Amazon Cognito User Pool
    Use a Cognito user pool configured as a part of this project.
    ? Do you want to configure advanced settings for the GraphQL API Yes, I want to make some additional changes.
    ? Configure additional auth types? Yes
    ? Choose the additional authorization types you want to configure for the API (Press  to select, a to toggle all, i to invert selection)
    ?Configure conflict detection? No

I wanted to confirm with you for Choose the additional authorization types you want to configure for the API (Press to select, a to toggle all, i to invert selection) did you select IAM and the press <space> before pressing enter? From the the transcript you posted, it looks like IAM was not selected.

Please feel free to re-open or comment in this thread if you are still facing this issue.

Was this page helpful?
0 / 5 - 0 ratings