Issue with authenticationContext.getUser() in servlet filter during Forge to Connect App invocation

We are beginning the migration of our Connect app to the Forge platform and have implemented the first step in the process.

In our Forge app:

  • We are using a custom UI.
  • We invoke the Forge resolver using @forge/bridge’s invoke() method.
  • Inside the resolver, we call our existing Connect app APIs using @forge/api’s invokeRemote().

On the Connect (Java-based) side:

  • We have annotated the target REST API methods with @ForgeRemote(associateConnect = true).
  • All required configurations have been added in the manifest.yml.

With this setup, everything is working as expected:

  • The request reaches our Connect app API successfully.
  • The API executes correctly.
  • Within the REST API, we are able to retrieve the user using authenticationContext.getUser().

The issue:

We have a Java Servlet Filter in our Connect app where we perform additional validations—such as checking the user’s role in our database—before allowing the request to proceed.

However, when the request comes from the Forge app via invokeRemote, inside the servlet filter, authenticationContext.getUser() returns null.
(Note: This works fine when the same API is called via Insight REST APIs or browser.)


Questions:

  1. What additional configuration or setup is needed so that authenticationContext.getUser() is available in the servlet filter when the call comes from Forge via invokeRemote()?
  2. Or, is there a recommended alternate approach to handle authentication and authorization in this kind of Forge-to-Connect communication?
  3. Is it expected that the user context is only available inside the API method annotated with @ForgeRemote, and not outside (e.g., in filters)?
  4. Can we manually extract the user context from headers or JWT if needed inside the filter? If yes, how?

I ended up with a different approach to the Connect to Forge migration because the current state of the ACSB library doesn’t work for me, also the unknown future of the library got me to move in a different direction.

However, for your case you can still use it.

Yes, it is, take a look at the RequireAuthenticationHandlerInterceptor
line 60 where it only calls the addConnectMappingToHostUser() method incase associateConnect is true.
It is within this addConnectMappingToHostUser() method that the user information is set in the authentication context.

To work around this you can use this code snippet (from the before mentioned interceptor at line 88) to get the user information you are looking for.

ForgeAuthentication forgeAuthentication = (ForgeAuthentication) SecurityContextHolder.getContext().getAuthentication();
Optional<AtlassianHostUser> hostUser = forgeConnectMappingService.getAtlassianHostUserFromForgeInvocationToken(forgeAuthentication.getDetails().getForgeInvocationToken());

The ForgeConnectMappingService can be injected into your filter.

Hope this helps.