Skip to content

feat: Flutter Windows Desktop support#656

Open
NandanPrabhu wants to merge 25 commits intomainfrom
SDK-6071
Open

feat: Flutter Windows Desktop support#656
NandanPrabhu wants to merge 25 commits intomainfrom
SDK-6071

Conversation

@NandanPrabhu
Copy link
Contributor

@NandanPrabhu NandanPrabhu commented Sep 8, 2025

  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

📋 Changes

This PR adds native Windows desktop support to the auth0_flutter SDK, enabling Auth0 Universal Login on Flutter Windows apps using the OAuth 2.0 Authorization Code Flow with PKCE. The implementation is a C++ Flutter plugin that integrates with the existing platform-interface layer without modifying the mobile (iOS/Android) code paths.


New: WindowsWebAuthentication class

A dedicated Windows authentication class exposed via Auth0.windowsWebAuthentication(). Unlike the mobile WebAuthentication class, this:

  • Requires redirectUrl explicitly (no platform default exists on Windows)
  • Does not auto-store credentials in CredentialsManager (no Keychain/Keystore on Windows)
  • Exposes a parameters map for Windows-specific configuration
final auth0 = Auth0('DOMAIN', 'CLIENT_ID');

// Simple: Auth0 redirects directly to the app via custom scheme
final credentials = await auth0.windowsWebAuthentication().login(
  redirectUrl: 'auth0flutter://callback',
);

// Intermediary server: HTTPS endpoint forwards to auth0flutter://callback
final credentials = await auth0.windowsWebAuthentication().login(
  redirectUrl: 'https://your-server.com/callback',
  parameters: {'authTimeoutSeconds': '300'},
);

authTimeoutSeconds (default '180'): How long the plugin polls for the OAuth callback before returning USER_CANCELLED. Increase for slow MFA flows; decrease for fast failure in tests.

Regardless of what redirectUrl is registered with Auth0, the Windows plugin always wakes the app by listening on the auth0flutter://callback custom scheme. When using an intermediary server, the server must forward the callback to auth0flutter://callback?code=…&state=….


New: Windows C++ plugin (auth0_flutter/windows/)

Component Purpose
login_web_auth_request_handler.cpp Orchestrates the full OAuth 2.0 + PKCE login flow
logout_web_auth_request_handler.cpp Builds and opens the Auth0 logout URL
oauth_helpers.cpp PKCE code verifier/challenge generation; auth0flutter:// callback polling
auth0_client.cpp HTTP token exchange via cpprestsdk
id_token_validator.cpp OpenID Connect ID token validation
id_token_signature_validator.cpp RS256 signature verification via OpenSSL
jwt_util.cpp JWT header/payload decoding
token_decoder.cpp Maps token exchange response → Credentials struct
user_profile.cpp / user_identity.cpp OIDC claims → UserProfile struct
time_util.cpp ISO 8601 / RFC 3339 timestamp parsing
url_utils.cpp RFC 3986 URL parsing and query parameter extraction
windows_utils.cpp WideToUtf8, BringFlutterWindowToFront

Authentication flow:

  1. Generate PKCE code_verifier (32 cryptographically random bytes via RAND_bytes) and code_challenge (SHA-256 via OpenSSL, base64-URL encoded)
  2. Generate a random state value for CSRF protection
  3. Build the Auth0 /authorize URL with all parameters RFC 3986-encoded
  4. Open the URL in the system default browser via ShellExecuteA
  5. Poll PLUGIN_STARTUP_URL environment variable (set by Windows when the app is launched via the auth0flutter:// custom scheme) every 200 ms until the callback arrives or the timeout expires
  6. Validate state to prevent CSRF; extract code
  7. Exchange code + code_verifier for tokens via POST to /oauth/token
  8. Validate the ID token (issuer, audience, expiry, auth_time, nonce, RS256 signature)
  9. Bring the Flutter window back to the foreground and return credentials

Key design decisions:

  • The app always listens on auth0flutter://callback (kDefaultRedirectUri). The redirectUrl sent to Auth0 may differ (e.g. an HTTPS intermediary server URL); that server is responsible for forwarding to auth0flutter://callback?code=…&state=….
  • Internal plugin parameters (authTimeoutSeconds) are consumed before building the authorize URL and are not appended to it.
  • The authentication flow runs on a background std::thread to avoid blocking the Flutter UI thread.
  • openid scope is always enforced even when not explicitly passed, as required by OpenID Connect.
  • All URL parameters are RFC 3986 percent-encoded to prevent injection and handle special characters in values such as redirect URIs and scopes.

New: vcpkg.json dependency manifest

Manages C++ dependencies via vcpkg, integrating automatically with CMake through the vcpkg toolchain file set by Flutter during flutter build windows:

Library Purpose
cpprestsdk Async HTTP client and JSON for token exchange
openssl RAND_bytes (PKCE entropy), SHA-256 (code challenge), RS256 signature verification, TLS
boost-system / boost-date-time / boost-regex Transitive cpprestsdk dependencies

New: Unit tests (Google Test, auth0_flutter/windows/test/)

Test file Coverage
oauth_helpers_test.cpp Base64-URL encoding, code verifier/challenge generation, callback timeout behaviour
id_token_validator_test.cpp Issuer, audience, expiry, auth_time, nonce, leeway validation
jwt_util_test.cpp JWT splitting, header/payload decoding
time_util_test.cpp ISO 8601 and RFC 3339 timestamp parsing
token_decoder_test.cpp Token response → Credentials mapping
url_utils_test.cpp URL parsing, query string extraction, RFC 3986 encoding
user_identity_test.cpp Identity claims extraction
user_profile_test.cpp User profile claims mapping
windows_utils_test.cpp WideToUtf8 wide-to-UTF-8 conversion

Tests are compiled as a separate auth0_flutter_tests executable and registered with CTest, enabled via -DAUTH0_FLUTTER_ENABLE_TESTS=ON.


New: CI pipeline (.github/workflows/main.yml)

Added a windows-tests job that installs vcpkg dependencies, builds the test executable with CMake, and runs all C++ unit tests via CTest on windows-latest.

📎 References


🎯 Testing

Automated — C++ unit tests (Windows)

cd auth0_flutter/windows
cmake -B build -S . \
  -DCMAKE_TOOLCHAIN_FILE=<vcpkg-root>/scripts/buildsystems/vcpkg.cmake \
  -DAUTH0_FLUTTER_ENABLE_TESTS=ON
cmake --build build
cd build && ctest --output-on-failure

All 9 test suites pass.

Automated — Flutter unit tests (any platform)

cd auth0_flutter
flutter test test/mobile/web_authentication_test.dart
# 34/34 tests pass

Manual — end-to-end on Windows

Prerequisites:

  1. Register auth0flutter as a custom URL scheme pointing to your app executable (via installer or registry)
  2. Add auth0flutter://callback to Allowed Callback URLs in the Auth0 dashboard
cd auth0_flutter/example
flutter run -d windows
  • Tap Log in → system default browser opens Auth0 Universal Login
  • Authenticate; browser redirects to auth0flutter://callback?code=…&state=…
  • Windows launches the app via the registered custom scheme; the Flutter window comes to the foreground and displays the returned credentials

To test the intermediary server pattern, point redirectUrl at an HTTPS endpoint that reads the code and state query parameters and responds with a redirect to auth0flutter://callback?code=…&state=….

(cherry picked from commit 6ad8d90)
…entage url encoding to login and logout urls - id token validation - presence of openid scope - code refactoring

(cherry picked from commit 5f1b308)
…e as app callback_url - params optional handling

(cherry picked from commit fd4b341ba06017c2c6a1ae1d1da36cf3bc20cc49)
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 61 out of 68 changed files in this pull request and generated 12 comments.

Files not reviewed (4)
  • .idea/.gitignore: Language not supported
  • .idea/auth0-flutter.iml: Language not supported
  • .idea/modules.xml: Language not supported
  • .idea/vcs.xml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

* main: (96 commits)
  Release af-v2.0.0-beta.5 (#768)
  fix: Show SSOCredentials (#767)
  Release af-v2.0.0-beta.4 (#764)
  chore: Fix RL Scanner pipeline (#763)
  Release afpi-v2.0.0-beta.4 (#762)
  chore: fix symlinks (#760)
  feat: add ssoExchange to AuthenticationApi for Native to Web SSO (#759)
  build(deps-dev): bump basic-ftp from 5.0.5 to 5.2.0 in /appium-test (#751)
  build(deps): bump actions/download-artifact from 7.0.0 to 8.0.0 (#754)
  build(deps): bump actions/upload-artifact from 6 to 7 in /.github/actions/unit-tests-darwin (#755)
  build(deps): bump nokogiri from 1.18.9 to 1.19.1 in /auth0_flutter/example/ios (#747)
  feat: Implement Native to Web (#749)
  build(deps): bump actions/upload-artifact from 6 to 7 (#753)
  build(deps): bump actions/upload-artifact from 6 to 7 in /.github/actions/smoke-tests-darwin (#756)
  build(deps): bump minimatch in /appium-test (#757)
  build(deps): bump fast-xml-parser and edgedriver in /appium-test (#758)
  chore: Removed PR analyzer (#752)
  build(deps): bump aws-actions/configure-aws-credentials from 5.1.1 to 6.0.0 in /.github/actions/rl-scanner (#744)
  chore:  updated the RL wrapper installation path (#746)
  Release af-v2.0.0-beta.3 (#743)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants