Forge's "External auth" authentication flow does not behave properly anymore

Forge’s External Authentication flow is now throwing an error when I try to authenticate my user a second time. This is a regression (it worked before).

Our app implements multiple external providers, Google and Microsoft. We use Custom UI and Forge Bridge for the front-end.

How Forge authentication flow works

The back-end implementation follows the documentation. Pseudocode:

function resolverFunction() {
  const google = api.asUser().withProvider("google", "google-drive");
  if (!(await google.hasCredentials(["scope1", "scope2"]))) {
    await google.requestCredentials();
  }
}

The front-end calls the resolver function, and when credentials are missing, requestCredentials returns a special response that replaces our iFrame’s content with a button that opens Forge’s Oauth2 authentication flow.

After the authentication flow is done, our iFrame is refreshed back to our front-end code, calling the resolver function again, hopefully resulting in a successful call (no requestCredentials was called again because hasCredentials is true).

The problem

The first authentication flow works properly (ex: Google), but subsequent authentications (ex: Microsoft) result in Forge throwing a “User consent was required again after consenting.” error in the final part of the authentication flow.

If I revoke all my “Atlassian third party account access” in Profile → Connected apps, then the next (first) authentication will proceed normally.

I have tested both possible sequences (“Google then Microsoft” or “Microsoft then Google”) and the second authentication will throw.

The error happens because hasCredentials returns false (and should be true). The new connection is successfully added in Profile → Connected Apps. But it takes ~5 minutes for the hasCredentials method to now return true.

Observation

I have noticed that an “Atlassian” access is also created in Profile → Connected apps:

It’s only created once (after the first connection) but not again the next time. I believe it used to create a new “Atlassian” line for every connection (I could be wrong here).


I hope a staff member from Atlassian can let me know if this is a known issue, and if I should raise this bug somewhere.

Kind regards,
Maxime

Hi @linklefebvre,

Multiple providers are supported, the providers manifest reference says an app may authenticate with multiple different providers. Two keys alone are fine.

Same class of thing: Stale hasCredentials results on external auth provider shows hasCredentials() is eventually consistent, false for up to about 2 minutes after a fresh consent there (5 here).

That fits your error. The iframe refreshes, hasCredentials() comes back stale false, requestCredentials() fires again, and you get consent required again. So I’d retry hasCredentials() for a few minutes before ever calling requestCredentials() a second time.

Haven’t reproduced it. For a firm answer raise it through ECOHELP with both timings, I couldn’t find a public ECO ticket for it.

Hi @Mihai_leanzero,

Thank you for the reply!

It used to work before so I knew this was supported.

Thanks for finding another post, I could not find one. It is indeed the same issue as mine. I can confirm both cases presented by the post were experienced by us.

Thanks for the solution idea, we could indeed do this. I would prefer we get an answer from Atlassian to be sure whether this is the intended behavior.

Hi @linklefebvre and @Mihai_leanzero,

This is unexpected and I’ve raised this with the internal team and they have found a likely culprit, you can track the remediation here: https://jira.atlassian.com/browse/ECO-1828

Thanks for the report!