How is your experience with the OutSystems Community?
21
Views
0
Comments
ODC + Keycloak Authentication: Callback Screen Opens Without Authorization Code

Hi guys, I got this issue when trying to get the authorization code returned by KeyCloak.
Environment

  • OutSystems Developer Cloud (ODC)
  • Mobile Application (Android and iOS)
  • Keycloak as Identity Provider
  • Authentication initiated using the ODC GetExternalLoginUrl() action

Current Flow

  1. User opens Login screen in the mobile application.
  2. The application checks whether the user is authenticated.
  3. If the user is not authenticated, the application calls GetExternalLoginUrl().
  4. ODC returns an authorization URL similar to the following:

https:/xxx.outsystems.app/auth/realms/.../protocol/openid-connect/auth?client_id=client_runtime&scope=openid&redirect_uri=app.xxx.mobile.dev://xxx-dev.outsystems.app/Android/Mobile/_RedirectLogin&response_type=code... 

  1. The user is redirected to Keycloak and enters their credentials.
  2. After successful authentication, the application returns to our mobile application and opens the KeycloakOAuthCallback screen.

Issue Observed

When KeycloakOAuthCallback is opened after the initial login, the URL is:

https:///Mobile/KeycloakOAuthCallback 

No authorization code is present.

We have verified this using:

  • window.location.href
  • Screen OnInitialize
  • Data Action OnAfterFetch
  • Screen OnReady
  • Delayed checks (up to 5 seconds)

The URL never changes and no code parameter becomes available.

This behavior is consistent across Android, iOS, and Web.

Additional Observation

When our callback logic detects that no authorization code is present, we currently trigger a second authentication request directly to Keycloak using:

https://xxxx/realms/xxxxs/protocol/openid-connect/auth?client_id=xxx&redirect_uri=xxxx://Mobile/KeycloakOAuthCallback&scope=openid&response_type=code... 

In this second flow:

  • Android automatically authenticates using the existing Keycloak session.
  • Web automatically authenticates using the existing Keycloak session.
  • iOS requires the user to enter credentials again.

After this second authentication request, our callback screen receives:

https:///Mobile/KeycloakOAuthCallback?code=... 

and we are able to successfully retrieve the authorization code.

Our Understanding

Based on our investigation, we suspect the following sequence may be occurring:

  1. Keycloak returns the authorization code to ODC's _RedirectLogin endpoint.
  2. ODC exchanges the authorization code with Keycloak for tokens.
  3. ODC creates the authenticated session.
  4. ODC then navigates to our KeycloakOAuthCallback screen without forwarding the original authorization code.

Could you please confirm whether this understanding is correct?

Business Requirement

We require both:

  1. ODC authentication and user provisioning/session management.
  2. Access to a Keycloak authorization code  so that we can call third-party APIs on behalf of the authenticated user.

Questions

  1. Does _RedirectLogin receive and exchange the authorization code before our application screen is opened?
  2. Is there any supported way to access the original authorization code when using GetExternalLoginUrl()?
  3. Is there any supported way to access the Keycloak access token, ID token, or JWT after ODC completes authentication?
  4. If direct access is not supported, what is the recommended architecture when both ODC authentication and downstream API access using the authenticated user's Keycloak token are required?
  5. Is the observed iOS behavior (requiring re-authentication during the second custom Keycloak login flow while Android and Web automatically authenticate) expected? Are there any known limitations related to iOS browser session or cookie handling?

We would appreciate any guidance or recommended implementation pattern for this scenario.

Thank you for your support.

Kind regards,

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.