-
Notifications
You must be signed in to change notification settings - Fork 56
Adding DPoP feature for flutter #667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 22 commits
fb1e954
59561ef
f36ce25
dcc06db
9f037ee
f97a18f
284b62f
df70633
bcf3a5a
ceb6c24
5b47793
8d7cc7e
866b1fb
3b7e369
36ebe7a
c317750
e3e6cb6
accc43b
a5f483d
a9d50cd
131f157
0e65bbf
2d46380
c3926f2
a29e2fd
8740337
e41aade
6071b97
5b8471d
16055d4
fbfb893
9cdf344
6c12e93
2ef754e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,7 +16,7 @@ env: | |
| ruby: '3.3.1' | ||
| flutter: '3.x' | ||
| ios-simulator: iPhone 16 | ||
| java: 11 | ||
| java: 17 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this needs to be upgraded ? |
||
|
|
||
| jobs: | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| # Migration Guide | ||
|
|
||
| ## Native SDK Version Updates | ||
|
|
||
| This release includes updates to the underlying native Auth0 SDKs to support new features including DPoP (Demonstrating Proof of Possession). These updates are **transparent** to your application code - no code changes are required unless you want to opt into new features like DPoP. | ||
|
|
||
| ### Updated SDK Versions | ||
|
|
||
| | Platform | Previous Version | New Version | Changes | | ||
| |----------|-----------------|-------------|---------| | ||
| | **Android** | Auth0.Android 2.11.0 | Auth0.Android 3.11.0 | DPoP support, **biometric auth requires FlutterFragmentActivity** | | ||
| | **iOS/macOS** | Auth0.swift 2.10.0 | Auth0.swift 2.14.0 | DPoP support, improved APIs | | ||
| | **Web** | auth0-spa-js 2.0 | auth0-spa-js 2.9.0 | DPoP support, bug fixes | | ||
|
|
||
| ### What's New | ||
|
|
||
| #### DPoP (Demonstrating Proof of Possession) Support | ||
| All platforms now support DPoP, an optional OAuth 2.0 security extension that cryptographically binds access tokens to your client, preventing token theft and replay attacks. | ||
|
|
||
| **This is an opt-in feature** - your existing authentication flows will continue to work without any changes. | ||
|
|
||
| To enable DPoP: | ||
| ```dart | ||
| // Mobile | ||
| final credentials = await auth0.webAuthentication().login(useDPoP: true); | ||
| // Web | ||
| final auth0Web = Auth0Web('DOMAIN', 'CLIENT_ID', useDPoP: true); | ||
| ``` | ||
|
|
||
| For complete DPoP documentation, see the [README](README.md#using-dpop-demonstrating-proof-of-possession). | ||
|
|
||
| ### Do I Need to Make Changes? | ||
|
|
||
| **Most users do not need to make changes.** However, there is one breaking change that affects users of biometric authentication on Android. | ||
|
|
||
| #### β οΈ Breaking Change: Android Biometric Authentication | ||
|
|
||
| **If you use biometric authentication on Android**, your `MainActivity.kt` must now extend `FlutterFragmentActivity` instead of `FlutterActivity`. | ||
|
|
||
| This requirement comes from Auth0.Android SDK 3.x, which changed its biometric authentication implementation. | ||
|
|
||
| **Who is affected:** | ||
| - β Users who call `credentialsManager.credentials()` with `localAuthentication` parameter | ||
| - β Only on Android platform | ||
| - β Only if your `MainActivity.kt` currently extends `FlutterActivity` | ||
|
|
||
| **Required change:** | ||
|
|
||
| ```kotlin | ||
| // Before (will cause error) | ||
| import io.flutter.embedding.android.FlutterActivity | ||
|
|
||
| class MainActivity: FlutterActivity() { | ||
| } | ||
|
|
||
| // After (required for biometric auth) | ||
| import io.flutter.embedding.android.FlutterFragmentActivity | ||
|
|
||
| class MainActivity: FlutterFragmentActivity() { | ||
| } | ||
| ``` | ||
|
|
||
| **If you don't use biometric authentication,** no changes are needed. | ||
|
|
||
| #### Optional New Features | ||
|
|
||
| You only need to make changes if you want to: | ||
| - β Enable DPoP for enhanced security (optional) | ||
| - β Use new iOS-only DPoP API methods: `getDPoPHeaders()` and `clearDPoPKey()` (optional) | ||
|
||
|
|
||
| ### Java Version Requirement (Android) | ||
|
|
||
| **Java 8** remains the minimum requirement for Android builds. The SDK continues to use: | ||
| - `sourceCompatibility JavaVersion.VERSION_1_8` | ||
| - `targetCompatibility JavaVersion.VERSION_1_8` | ||
utkrishtsahu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| No changes to your Java setup are needed. | ||
|
|
||
| ## What's New | ||
|
|
||
| This version includes support for **DPoP (Demonstrating Proof of Possession)**, an optional OAuth 2.0 security feature that cryptographically binds access tokens to a specific client. DPoP is completely opt-in and your existing authentication flows will continue to work without any modifications. | ||
|
|
||
| For detailed DPoP usage instructions, see the [README DPoP section](README.md#using-dpop-demonstrating-proof-of-possession). | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -202,6 +202,10 @@ Re-declare the activity manually using `tools:node="remove"` in the `android/src | |
|
|
||
| > π‘ If your Android app is using [product flavors](https://developer.android.com/studio/build/build-variants#product-flavors), you might need to specify different manifest placeholders for each flavor. | ||
|
|
||
| ##### Android: Biometric authentication | ||
|
|
||
| > β οΈ On Android, your app's `MainActivity.kt` file must extend `FlutterFragmentActivity` instead of `FlutterActivity` for biometric prompts to work. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be considered a breaking change for customer who currently uses biometric authentication ? |
||
|
|
||
| ##### iOS/macOS: Configure the associated domain | ||
|
|
||
| > β οΈ This step requires a paid Apple Developer account. It is needed to use Universal Links as callback and logout URLs. | ||
|
|
@@ -343,6 +347,44 @@ final credentials = await auth0Web.loginWithPopup(popupWindow: popup); | |
|
|
||
utkrishtsahu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| For other comprehensive examples, see the [EXAMPLES.md](EXAMPLES.md) document. | ||
|
|
||
| ### Using DPoP (Demonstrating Proof of Possession) | ||
|
|
||
| Auth0 Flutter SDK supports [DPoP (Demonstrating Proof of Possession)](https://datatracker.ietf.org/doc/html/rfc9449), a security mechanism that cryptographically binds access tokens to your client, preventing token theft and replay attacks. | ||
|
|
||
| **Quick Start:** | ||
|
|
||
| ```dart | ||
| // Mobile (Android/iOS) | ||
| final credentials = await auth0 | ||
| .webAuthentication() | ||
| .login(useDPoP: true, useHTTPS: true); | ||
|
|
||
| // Web | ||
| final auth0Web = Auth0Web( | ||
| 'YOUR_AUTH0_DOMAIN', | ||
| 'YOUR_AUTH0_CLIENT_ID', | ||
| useDPoP: true, | ||
| ); | ||
| ``` | ||
|
|
||
| **Key Benefits:** | ||
| - π Enhanced security through cryptographic token binding | ||
| - π‘οΈ Protection against token theft and replay attacks | ||
| - π Full cross-platform support (Web, Android, iOS) | ||
|
|
||
| **Platform Support:** | ||
|
|
||
| | Feature | Web | iOS | Android | | ||
| |---------|-----|-----|---------| | ||
| | Login with DPoP | β | β | β | | ||
| | CredentialsManager with DPoP | β | β | β | | ||
| | Token Refresh with DPoP | β | β | β | | ||
| | Manual DPoP APIs (`getDPoPHeaders()`, `clearDPoPKey()`) | β | β | β | | ||
|
|
||
| > **Note:** In most cases, DPoP is managed automatically when `useDPoP: true` is enabled. Manual DPoP APIs are available for advanced use cases where you need direct control over DPoP proof generation. | ||
|
|
||
| π **For complete DPoP documentation, examples, and troubleshooting, see [DPOP.md](DPOP.md)** | ||
|
|
||
| ### iOS SSO Alert Box | ||
|
|
||
|  | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| distributionBase=GRADLE_USER_HOME | ||
| distributionPath=wrapper/dists | ||
| distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip | ||
| distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip | ||
| zipStoreBase=GRADLE_USER_HOME | ||
| zipStorePath=wrapper/dists |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| package com.auth0.auth0_flutter | ||
|
|
||
| import androidx.annotation.NonNull | ||
| import io.flutter.plugin.common.MethodCall | ||
| import io.flutter.plugin.common.MethodChannel.MethodCallHandler | ||
| import io.flutter.plugin.common.MethodChannel.Result | ||
|
|
||
| /** | ||
| * Composite handler that delegates method calls to either DPoP or Auth handlers. | ||
| * DPoP handlers are tried first, then falls back to Auth handlers. | ||
| */ | ||
| class Auth0FlutterCompositeMethodCallHandler( | ||
| private val dpopHandler: Auth0FlutterDPoPMethodCallHandler, | ||
|
||
| private val authHandler: Auth0FlutterAuthMethodCallHandler | ||
| ) : MethodCallHandler { | ||
|
|
||
| override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { | ||
| // Track if the method was handled | ||
| var handled = false | ||
|
|
||
| // Create a result wrapper to detect if DPoP handler processed the call | ||
| val dpopResult = object : Result { | ||
| override fun success(data: Any?) { | ||
| handled = true | ||
| result.success(data) | ||
| } | ||
|
|
||
| override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) { | ||
| handled = true | ||
| result.error(errorCode, errorMessage, errorDetails) | ||
| } | ||
|
|
||
| override fun notImplemented() { | ||
| // DPoP didn't handle it, don't mark as handled | ||
| handled = false | ||
| } | ||
| } | ||
|
|
||
| // Try DPoP handler first | ||
| dpopHandler.onMethodCall(call, dpopResult) | ||
|
|
||
| // If DPoP didn't handle it, try auth handler | ||
| if (!handled) { | ||
| authHandler.onMethodCall(call, result) | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package com.auth0.auth0_flutter | ||
|
|
||
| import androidx.annotation.NonNull | ||
| import com.auth0.auth0_flutter.request_handlers.api.UtilityRequestHandler | ||
| import com.auth0.auth0_flutter.request_handlers.MethodCallRequest | ||
| import io.flutter.plugin.common.MethodCall | ||
| import io.flutter.plugin.common.MethodChannel.MethodCallHandler | ||
| import io.flutter.plugin.common.MethodChannel.Result | ||
|
|
||
| /** | ||
| * Handler for DPoP-related method calls. | ||
| * DPoP (Demonstration of Proof-of-Possession) operations use static utility methods | ||
| * and don't require authentication API client instances. | ||
| */ | ||
| class Auth0FlutterDPoPMethodCallHandler( | ||
| private val dpopRequestHandlers: List<UtilityRequestHandler> | ||
| ) : MethodCallHandler { | ||
|
|
||
| override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { | ||
| val request = MethodCallRequest.fromCall(call) | ||
|
|
||
| // Find the matching DPoP handler | ||
| val dpopHandler = dpopRequestHandlers.find { it.method == call.method } | ||
|
|
||
| if (dpopHandler != null) { | ||
| dpopHandler.handle(request, result) | ||
| } else { | ||
| result.notImplemented() | ||
| } | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.