Skip to content

feat: Flutter Windows Desktop support#656

Open
NandanPrabhu wants to merge 46 commits intobeta-release/v.2.1.0from
SDK-6071
Open

feat: Flutter Windows Desktop support#656
NandanPrabhu wants to merge 46 commits intobeta-release/v.2.1.0from
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 appCallbackUrl explicitly
  • Does not auto-store credentials in CredentialsManager
final auth0 = Auth0('DOMAIN', 'CLIENT_ID');

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

// Intermediary server: HTTPS endpoint forwards to auth0flutter://callback
final credentials = await auth0.windowsWebAuthentication().login(
  appCallbackUrl: 'myapp://callback',
 redirectUrl: 'https://myhosteddomain.com/callback
);

Regardless of what redirectUrl is registered with Auth0, the Windows plugin always wakes the app by listening on the myapp://callback custom scheme. When using an intermediary server, the server must forward the callback to myapp://callback?code=…&state=…. This custom scheme to passed to windows native code from dart via the appCallbackUrl parameter


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 myapp://callback or 'https://mycustomhosteddomain.com/callback" to Allowed Callback URLs and **AllowedLogout 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 myApp://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=….

nandan-bhat
nandan-bhat previously approved these changes Mar 26, 2026
…lidation mirrors swift sdk - CI fixes adding caching to reduce build times
(cherry picked from commit bab56bb077b543f5db812533a6e5c3bbdf813077)
…e logic is bit refactored to read from scopes and parameters[scope]
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