Skip to content

Android client PKCE login hangs after MFA — WebView fails to intercept localhost:53000 redirect #194

Description

@neighbour-oldhuang

Description

When using the Android client with a self-hosted NetBird server (embedded IdP, local email/password authentication with TOTP MFA), the PKCE login flow hangs indefinitely after successfully completing MFA verification. The
Windows client works correctly with the same server and account.

Steps to Reproduce

  1. Configure self-hosted NetBird with embedded IdP (combined server mode)
  2. Create a local
  3. Create a local user with email/password + TOTP MFA enabled
  4. On Android client, select "Email" login option
  5. Enter email and password → success
  6. Enter TOTP code → success
  7. App hangs at this point — never completes login

Expected Behavior

After MFA verification succeeds, the app should extract the authorization code from the redirect and exchange it for a token, completing the login.

Actual Behavior

The app's embedded WebView receives a 303 redirect to http://localhost:53000/?code=xxx&state=xxx from the /oauth2/approval endpoint, but fails to intercept this redirect. The WebView appears to get stuck attempting to
load the localhost URL instead of the app capturing the authorization code from the URL.

Server-Side Evidence

Traefik access logs show the complete successful flow:

Password login success (303)

POST /oauth2/auth/local/login?... 303

MFA TOTP success (303)

POST /oauth2/mfa/totp?... 303

Approval redirects to localhost:53000 (303, 140 bytes)

GET /oauth2/approval?... 303 140

*** No subsequent POST /oauth2/token request from Android ***

For comparison, Windows client successfully issues POST /oauth2/token immediately after the approval redirect and completes login.

Environment

  • Server version: 0.72.2 (combined server mode, embedded IdP)
  • Android client: latest from Play Store
  • Auth method: Local email/password + TOTP MFA
  • Login option selected: "Email" (PKCE flow)

Workaround

Using the "SSO" login option (which triggers Device Authorization Flow) works correctly on Android. The device flow does not depend on localhost redirect interception.

Notes

  • The Android client calls GetPKCEAuthorizationFlow via gRPC and uses redirect_uri=http://localhost:53000/ with an embedded WebView (not an external browser).
  • The issue appears to be that shouldOverrideUrlLoading or equivalent WebView URL interception is not capturing the http://localhost:53000/ redirect after the 303 from /oauth2/approval.
  • Device Flow (POST /oauth2/device/code → poll token endpoint) has been verified working on the same Android device with the same account

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions