generic-oauth2
generic-oauth2 copied to clipboard
Bug: Error: ERR_GENERAL (1000 - invalid request - duplicated parameter)
Capacitor version:
Run npx cap doctor
:
💊 Capacitor Doctor 💊
Latest Dependencies:
@capacitor/cli: 4.3.0
@capacitor/core: 4.3.0
@capacitor/android: 4.3.0
@capacitor/ios: 4.3.0
Installed Dependencies:
@capacitor/cli: 4.3.0
@capacitor/android: 4.3.0
@capacitor/ios: 4.3.0
@capacitor/core: 4.3.0
[error] Xcode is not installed
[success] Android looking great! 👌
Library version:
- other: 4.0.0
OAuth Provider:
- Other: Keycloak
Your Plugin Configuration
{
authorizationBaseUrl:
"https://login.example.com/auth/realms/myrealm/protocol/openid-connect/auth",
accessTokenEndpoint:
"https://login.example.com/auth/realms/myrealm/protocol/openid-connect/token",
scope: "openid",
resourceUrl:
"https://login.example.com/auth/realms/myrealm/protocol/openid-connect/userinfo",
logoutUrl:
"https://login.example.com/auth/realms/myrealm/protocol/openid-connect/logout",
logsEnabled: true,
additionalParameters: {
nonce: this.generateNonce(),
},
web: {
appId: "com-test-app",
responseType: "token",
accessTokenEndpoint: "",
resourceUrl: "",
redirectUrl: "http://localhost:8080",
windowOptions: "height=600,left=0,top=0",
},
android: {
appId: "com-test-app",
responseType: "code",
redirectUrl: "com.test.app:/",
},
ios: {
appId: "com-test-app",
responseType: "code",
redirectUrl: "com.test.app:/",
}
}
I needed to add nonce
manually, it is generated like this:
generateNonce() {
const crypto = require("crypto");
return crypto.randomBytes(16).toString("base64");
}
Affected Platform(s):
- Android
- Version/API Level: 31
- Device Model: Android emulator version 31.2.10.0
- Content of your
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.test.app">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
android:name="com.test.app.MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBarLaunch"
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"></meta-data>
</provider>
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
Current Behavior
The app is building and loading up fine in the emulator. When I initiate the login process using a button, nothing happens in the app. The following log is in chrome://inspect:
(index):243 native OAuth2Client.authenticate (#67926799)
{
"callbackId": "67926799",
"pluginId": "OAuth2Client",
"methodName": "authenticate",
"options": {
"authorizationBaseUrl": "https://login.example.com/auth/realms/myrealm/protocol/openid-connect/auth",
"accessTokenEndpoint": "https://login.example.com/auth/realms/myrealm/protocol/openid-connect/token",
"scope": "openid",
"resourceUrl": "https://login.example.com/auth/realms/myrealm/protocol/openid-connect/userinfo",
"logoutUrl": "https://login.example.com/auth/realms/myrealm/protocol/openid-connect/logout",
"logsEnabled": true,
"additionalParameters": {
"nonce": "DGeGZwKlWa2oO8qsATSQ+A=="
},
"web": {
"appId": "com-test-app",
"responseType": "token",
"accessTokenEndpoint": "",
"resourceUrl": "",
"redirectUrl": "http://localhost:8080",
"windowOptions": "height=600,left=0,top=0"
},
"android": {
"appId": "com-test-app",
"responseType": "code",
"redirectUrl": "com.test.app:/"
},
"ios": {
"appId": "com-test-app",
"responseType": "code",
"redirectUrl": "com.test.app:/"
}
}
}
(index):217 result OAuth2Client.authenticate (#67926799)
(index):225 {message: 'ERR_GENERAL'}message: "ERR_GENERAL"
AuthView.vue:64 =======OAuth rejected======= Error: ERR_GENERAL
at returnResult ((index):714:32)
at win.androidBridge.onmessage ((index):689:21)
Logcat snippet from the time when the button was clicked:
10-14 13:57:24.195 533 2756 I ActivityTaskManager: START u0 {dat=com.f24.capacitoroath2:/?error=invalid_request&error_description=duplicated+parameter&state=nEa02tgQdH05IgMStNB5 flg=0x24000000 cmp=com.f24.capacitoroath2/net.openid.appauth.AuthorizationManagementActivity} from uid 10159
10-14 13:57:24.197 350 411 D goldfish-address-space: claimShared: Ask to claim region [0x3fb57d000 0x3fbb2f000]
10-14 13:57:24.200 20278 20327 I cr_BindingManager: onTrimMemory: level=20, size=0
10-14 13:57:24.215 9873 9873 I Zygote : Process 25292 exited cleanly (0)
10-14 13:57:24.225 533 2756 W ActivityTaskManager: Duplicate finish request for r=ActivityRecord{fb7e0fc u0 com.f24.capacitoroath2/net.openid.appauth.RedirectUriReceiverActivity t54 f}}
10-14 13:57:24.271 350 411 D goldfish-address-space: claimShared: Ask to claim region [0x3f6a10000 0x3f6fc2000]
10-14 13:57:24.298 350 411 D goldfish-address-space: claimShared: Ask to claim region [0x3f4dc8000 0x3f56af000]
10-14 13:57:24.308 350 411 D goldfish-address-space: claimShared: Ask to claim region [0x3f56af000 0x3f5f96000]
10-14 13:57:24.316 350 411 D goldfish-address-space: claimShared: Ask to claim region [0x3f84db000 0x3f8dc2000]
10-14 13:57:24.347 31633 31633 D Capacitor: Unable to find a Capacitor plugin to handle requestCode, trying Cordova plugins 473291342
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: ERR_GENERAL
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: AuthorizationException: {"type":1,"code":1000,"error":"invalid_request","errorDescription":"duplicated parameter"}
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at com.byteowls.capacitor.oauth2.OAuth2ClientPlugin.handleAuthorizationRequestActivity(OAuth2ClientPlugin.java:342)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at com.byteowls.capacitor.oauth2.OAuth2ClientPlugin.handleIntentResult(OAuth2ClientPlugin.java:330)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at java.lang.reflect.Method.invoke(Native Method)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at com.getcapacitor.Plugin.triggerActivityCallback(Plugin.java:155)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at com.getcapacitor.Plugin.lambda$initializeActivityLaunchers$0$com-getcapacitor-Plugin(Plugin.java:117)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at com.getcapacitor.Plugin$$ExternalSyntheticLambda0.onActivityResult(Unknown Source:6)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at androidx.activity.result.ActivityResultRegistry.doDispatch(ActivityResultRegistry.java:409)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at androidx.activity.result.ActivityResultRegistry.dispatchResult(ActivityResultRegistry.java:366)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at androidx.activity.ComponentActivity.onActivityResult(ComponentActivity.java:712)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at androidx.fragment.app.FragmentActivity.onActivityResult(FragmentActivity.java:140)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at com.getcapacitor.BridgeActivity.onActivityResult(BridgeActivity.java:173)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at android.app.Activity.dispatchActivityResult(Activity.java:8382)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at android.app.ActivityThread.deliverResults(ActivityThread.java:5294)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at android.app.ActivityThread.handleSendResult(ActivityThread.java:5340)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:54)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at android.os.Handler.dispatchMessage(Handler.java:106)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at android.os.Looper.loopOnce(Looper.java:201)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at android.os.Looper.loop(Looper.java:288)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at android.app.ActivityThread.main(ActivityThread.java:7839)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at java.lang.reflect.Method.invoke(Native Method)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
10-14 13:57:24.352 31633 31633 E Capacitor/Plugin: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
10-14 13:57:24.353 31633 31633 D Capacitor: Sending plugin error: {"save":false,"callbackId":"77015471","pluginId":"OAuth2Client","methodName":"authenticate","success":false,"error":{"message":"ERR_GENERAL"}}
10-14 13:57:24.361 31633 31633 D Capacitor: App resumed
10-14 13:57:24.368 31633 31633 I Capacitor/Console: File: http://localhost/js/app.c6b49c91.js - Line 1 - Msg: =======OAuth rejected======= Error: ERR_GENERAL
Log highlighs:
...
dat=com.test.app:/?error=invalid_request&error_description=duplicated+parameter&state=nEa02tgQdH05IgMStNB5
...
...
Capacitor/Plugin: ERR_GENERAL
Capacitor/Plugin: AuthorizationException: {"type":1,"code":1000,"error":"invalid_request","errorDescription":"duplicated parameter"}
...
Expected Behavior
Initiate authentication by opening the keycloak SSO login page.
Other Information
This is a simple Capacitor + VueJS test app. Android redirectUrl was saved as valid redirect uri in keycloak. On the platform Web the Keycloak login page is opened correctly, login works and the server gives a response containing the access_token. iOS was not tested at all at this stage.
I am seeing this issue also on android - it seems a 'nonce' is being automatically added to the request - so when we try to add nonce manually, it is being duplicated. However it does not seem that this package deals with automatically generating a nonce so im not sure how its ending up in the request.
~~Have you managed to find a solution?~~
EDIT: the duplicated parameter is being generated by the AuthorizationRequest.Builder class from the AppAuth library