capacitor-community/generic-oauth2

Azure B2C - redirect uri provided in the request is not registered for the client id

loonix opened this issue ยท 22 comments

Description

Hi guys, I am able to login using the web configs but when I try to login on android it seems that it is not working for me, would be great if someone can give me some help with this.

Steps

  1. Open emulator with app
  2. Click Login
  3. Accesses the login page (azure)
  4. Automatically returns to the app
  5. Throws an error

Chrome Inspector:

main.js:1265 OAuth rejected Error: ERR_GENERAL
    at Object.fromNative (capacitor-runtime.js:226)
    at <anonymous>:1:18

Android Studio:

2020-05-14 11:48:31.958 26720-26720/com.cads.testapp E/Capacitor/Plugin: ERR_GENERAL
    AuthorizationException: {"type":1,"code":1008,"error":"redirect_uri_mismatch","errorDescription":"AADB2C90006: The redirect URI 'com.cads.testapp:\/\/oauth\/redirect' provided in the request is not registered for the client id 'XXXXXXXX-XXXXXXX-XXXXXXX'.\r\nCorrelation ID: XXXXX-XXXXXX-XXXXXX\r\nTimestamp: 2020-05-14 10:48:30Z\r\n"}
        at com.byteowls.capacitor.oauth2.OAuth2ClientPlugin.handleAuthorizationRequestActivity(OAuth2ClientPlugin.java:333)
        at com.byteowls.capacitor.oauth2.OAuth2ClientPlugin.handleOnActivityResult(OAuth2ClientPlugin.java:321)
        at com.getcapacitor.Bridge.onActivityResult(Bridge.java:770)
        at com.getcapacitor.BridgeActivity.onActivityResult(BridgeActivity.java:212)
        at android.app.Activity.dispatchActivityResult(Activity.java:7454)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4353)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4402)
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
2020-05-14 11:48:31.971 26720-26720/com.cads.smartanchortest E/Capacitor/Console: File: http://localhost/main.js - Line 1265 - Msg: OAuth rejected

Capacitor version: 2.1.0

Capacitor Doctor
Latest Dependencies:
  @capacitor/cli: 2.1.0
  @capacitor/core: 2.1.0
  @capacitor/android: 2.1.0
  @capacitor/electron: 2.1.0
  @capacitor/ios: 2.1.0

Installed Dependencies:
  @capacitor/electron not installed
  @capacitor/cli 2.0.0
  @capacitor/ios 2.0.0
  @capacitor/core 2.0.0
  @capacitor/android 2.0.0
[success] Android looking great! ๏ฟฝ

Library version: 2.0.0

OAuth Provider: Azure B2C

Your Plugin Configuration

{
    appId: 'XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX,
    authorizationBaseUrl: 'https://TENANT.b2clogin.com/tfp/TENANT.onmicrosoft.com/B2C_1_policy-signin-signup-web/oauth2/v2.0/authorize',
    accessTokenEndpoint: '',
    scope: 'https://XXXXXXX.onmicrosoft.com/TestApi4/demo.read',
    responseType: 'token',
    web: {
      redirectUrl: 'http://localhost:8100/'
    },
    android: {
      pkceEnabled: true,
      responseType: 'code',
      redirectUrl: 'com.cads.testapp://oauth/redirect',
      accessTokenEndpoint: 'https://TENANT.b2clogin.com/TENANT.onmicrosoft.com/B2C_1_policy-signin-signup-web',
      handleResultOnNewIntent: true,
      handleResultOnActivityResult: true
    },
    ios: {
      pkceEnabled: true,
      responseType: 'code',
      redirectUrl: 'com.cads.testapp://oauth',
      accessTokenEndpoint: 'https://TENANT.b2clogin.com/TENANT.onmicrosoft.com/B2C_1_policy-signin-signup-web',
    }
}

Notes:

I have checked the azure settings and I have configured the Custom Redirect URI to com.cads.testapp://oauth/redirect but still am facing this issue.

If I change the following:

{
...
handleResultOnNewIntent: true,
handleResultOnActivityResult: false
...
}

It opens the login page and redirects to the app but does not give any error, but it does not pass any parameter either

EDIT:
it seems that the redirect URI add a backslash before :
The redirect URI 'com.cads.testapp:\/\/oauth\/redirect' provided in the request is not registered for the client id

Has anyone came across this issue, or knows a way to fix this? Many thanks for the awesome plugin!

Have a look at #91. Try the proposed steps there to debug your problem. BR

@moberwasserlechner I did take a look an followed the steps in there (unless I missed something) but till the same problem. It seems a bit weird but I do get this on the error:
'com.cads.testapp:\/\/oauth\/redirect' which should be 'com.cads.testapp://oauth/redirect' that might be the issue but I am stuck and get around this. :(

Try this:

android: {
      pkceEnabled: true,
      responseType: 'code',
      redirectUrl: 'com.cads.testapp://oauth/redirect',
      accessTokenEndpoint: 'https://TENANT.b2clogin.com/TENANT.onmicrosoft.com/B2C_1_policy-signin-signup-web',
      handleResultOnNewIntent: true,
      handleResultOnActivityResult: true
    },

strings.xml:

<string name="custom_url_scheme">com.cads.testapp://oauth/redirect</string>

AndroidManifest:

<data android:scheme="com.cads.testapp" android:host="auth" />

build.gradle:

defaultConfig {
        // other stuff
        manifestPlaceholders = [
            "appAuthRedirectScheme": "com.cads.testapp"
        ]

Azure portal:

Include web app / web API: YES
Allow implicit flow: YES
Include native client: YES
Custom Redirect URI: com.cads.testapp://oauth/redirect

@fredbjork

In your example you do not use the value reference from strings.xml in the your AndroidManifest.

Therefore changing the value in strings.xml should not be needed. Have you tried to remove it.

You have

<data android:scheme="com.cads.testapp" android:host="oauth" />

instead of

<data android:scheme="@string/custom_url_scheme" android:host="oauth" />

The strings.xml should include only the scheme. No context path like ://oauth/redirect. See Cap docs for changing the custom scheme

I'll try to clearify that in the README.

@loonix Could you plz have a look at this README section I tried to clearify a few things based on this task and the input from @fredbjork

You are right, could probably just remove the value in strings.xml if you dont use it in AndroidManifest.

@moberwasserlechner made a comment on the change

@fredbjork thanks forsharing the code but it seems that has not made any change to me I still get that error unfortunately :(

I still haven't managed to get it to work but I have created an example of implementation of azure b2c, maybe its easier to see the code

https://github.com/loonix/capacitor-oauth2-azure-example

The repo looks good. Everything is there, so I really don't know why it does not work.

Try to add "openid" (and "offline_access") to your scope string and add those permissions to your App. Then "Grant admin consent for tenant B2C".

Screenshot 2020-05-14 at 23 20 08

@fredbjork will try that, what type of app did you register on azure?
image

@fredbjork @moberwasserlechner many thanks for your help, it seems that it was a typo on theredirectUrl that triggered that, after looking closer that was the issue

@moberwasserlechner please feel free to link my capacitor example to your readme-file as it is working well

PS: the / escape I think it is due to the json encoding that outputs that to the terminal..

for anyone experiencing the issue BAD REQUEST just make sure you add the code in MainActivity.java

... Other imports
import com.byteowls.capacitor.oauth2.OAuth2ClientPlugin; // <-- this

public class MainActivity extends BridgeActivity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Initializes the Bridge
    this.init(savedInstanceState, new ArrayList<Class<? extends Plugin>>() {{
      // Additional plugins you've installed go here
      // Ex: add(TotallyAwesomePlugin.class);
      add(OAuth2ClientPlugin.class); // <-- this
    }});
  }
}

@loonix I'm glad you solved your config issue.

Don't get me wrong but I try to prevent such tasks with documentation in the README. So just one final question:

There was no bug in the plugin or in the documentation. If you had followed the Android section in the README and did not had the typo in your config everything would be fine?

The problem was not the specification (although it did helped when you added the paths for placing the changes in the right place) it was really a typo on azure configuration. Documentation looks good, I created a fresh repo just to be easier to isolate the issue I was having.

When I have the IOS version working as well I will update the code so it gets easier for someone else that comes across this.

Sorry for all the questions and thanks for the help from both.

@loonix Thx for the answer and for the repo.

I linked it here and copied your config as another example for azure b2c.

PS: My comment was not meant to be offending in any kind. Your questions helped to make the docs more helpful, especially for devs, that are new to Capacitor and OAuth.
PSS: I keep this task open until you finish the iOS part and if you have questions please ask.

Hey, is your logout function working? I am trying and it seems that it does not work with Azure.
Is there any logout url we have to provide on the configs?

  onLogoutClick() {
    Plugins.OAuth2Client.logout(environment.oauth2Options)
      .then(() => sessionStorage.clear())
      .catch(reason => { console.error('OAuth logout failed', reason); });
  }

The current logout function is not what you expect. It simply cleans any cached tokens but does not log you out of the provider. For that to work you would have to provide a logout url, which is not supported (yet).

But you can create a new feature request task and I try to include that in one of the upcoming releases, but I can't give you a timeline.

@loonix Is this issue ready to close? The logout feature request got its own task. Did you had any issues on iOS?

I still haven't tested, but feed free to close it, I will reopen if there is an issue. Thanks

But could you plz open a new issue in case of a iOS problem. With all the discussion in this one it is would be hard to keep track of the new problem. thx