capacitor-community / generic-oauth2

Generic Capacitor OAuth 2 client plugin. Stop the war in Ukraine!
MIT License
223 stars 106 forks source link

Bug: Error: ERR_GENERAL (1000 - invalid request - duplicated parameter) #219

Open athyla opened 1 year ago

athyla commented 1 year ago

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:

OAuth Provider:

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):



### Current Behavior
<!-- Describe the bug. Be specific. I need to understand you problem. -->
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:
```typescript
(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
<!-- Describe what the behavior would be without the bug. -->
Initiate authentication by opening the keycloak SSO login page.

### Other Information
<!-- List any other information that is relevant to your issue. Stack traces, related issues, suggestions on how to fix, Stack Overflow links, forum links, etc. -->
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. 
brad-e20 commented 1 year ago

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