capacitor-community / generic-oauth2

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

How to use windowTarget: "_self" #220

Closed atmike closed 1 year ago

atmike commented 1 year ago

Description

Hello I have the problem that I can not use the plugin with the combination of windowTarget: "_self", and responseType: "token". I need to address two AD's for a project. One Azure AD and one Azure B2C AD. But when I do this I always get the following error message with the below configuration for B2C error_description=AADB2C90205:+This+application+does+not+have+sufficient+permissions+against+this+web+resource+to+perform+the+operation. %0D%0ACorrelation+ID:+59b878c4-3fba-4b74-9e99-dcea2471a374%0D%0ATimestamp:+2022-10-24+19:52:29Z%0D%0A&state=C4D4Mvzj4RjkSTPyzExf I have set the permissions in both apps in Azure, incl. admin permissions API image APP image

If I combine windowTarget: "_self", with responseType: "code" it works, but then I get back as URL parameter the authorization code but I can't get the token out of it.

So my question is. How can I leave windowTarget: "_self" and get the token from the Plugin?

Thank you for helping me.

Capacitor version:

4.0.0

Library version:

4.0.0

OAuth Provider:

Your Plugin Configuration

{
 getAzureInternalOAuth2Options(): OAuth2AuthenticateOptions {
    var tenantId = "6273e691-1111-2222-3333-e5267d5da3a6"; 
    var appId = "283a2967-1111-2222-3333-b249c0d72231";
    var redirectUrlWeb = "http://localhost:4200"; 
    return {
      appId: appId,
      authorizationBaseUrl: `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize`,
      scope: "https://graph.microsoft.com/User.Read", 
      accessTokenEndpoint: `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,
      resourceUrl: "https://graph.microsoft.com/v1.0/me/",
      responseType: "token",
      pkceEnabled: true,
      logsEnabled: true,
      web: {
        redirectUrl: redirectUrlWeb,
        windowTarget: "_self",
        windowOptions: "height=600,left=0,top=0",
      },
      android: {
        redirectUrl: "msauth://{package-name}/{url-encoded-signature-hash}"
      },
      ios: {
        pkceEnabled: true, 
        redirectUrl: "msauth.{package-name}://auth"
      }
    };
  }

  getAzureB2COAuth2Options(): OAuth2AuthenticateOptions {
    var tenantId = "NameOfTheTenant"; 
    var appId = "066ed81b-0000-1111-2222-e5a54bc76fac";
    var redirectUrlWeb = "http://localhost:4200"; 
    var policyName: string = "B2C_1_susi";
    return {
      appId: appId,
      responseType: "token",
      authorizationBaseUrl: `https://${tenantId}.b2clogin.com/${tenantId}.onmicrosoft.com/${policyName}/oauth2/v2.0/authorize`,
      accessTokenEndpoint: '',
      scope: `https://${tenantId}.onmicrosoft.com/tasks-armawin`, 
      resourceUrl: "https://graph.microsoft.com/v1.0/me/",
      pkceEnabled: true,
      logsEnabled: true,
      web: {
        redirectUrl: redirectUrlWeb,
        windowTarget: "_self",
        windowOptions: "height=600,left=0,top=0"
      },
      android: {
        redirectUrl: "msauth://{package-name}/{url-encoded-signature-hash}" 
      },
      ios: {
        pkceEnabled: true, // workaround for bug #111
        redirectUrl: "msauth.{package-name}://auth"
      }
    };
  }
}

Affected Platform(s):

atmike commented 1 year ago

@moberwasserlechner Hello Michael, Sorry to bother you but would need your help urgently. As you saw above, I am currently trying to perform an Azure B2C login using your component. The login is working and I also get the authentication code and the status back.

But I can't really get any further from here. I have already tried to rebuild the token retrieval and have looked at your code => ` async handleCallback(authorizationCode: string) { const webOptions = await WebUtils.buildWebOptions(this.getAzureB2COAuth2Options());

this.oauth2Options = this.getAzureB2COAuth2OptionsDialog();
if (this.oauth2Options && this.oauth2Options.accessTokenEndpoint) {
    const service = this;
    const tokenRequest = new XMLHttpRequest();
    tokenRequest.onload = function () {
      if (this.status === 200) {
        let accessTokenResponse = JSON.parse(this.response);
        console.log("Access token response:", accessTokenResponse);
      }
    };
    tokenRequest.onerror = function () {
      console.error("ERR_GENERAL: See client logs. It might be CORS. Status text: " + this.statusText);
    };
    tokenRequest.open("POST", this.oauth2Options.accessTokenEndpoint, true);
    tokenRequest.setRequestHeader('accept', 'application/json');
    tokenRequest.setRequestHeader('cache-control', 'no-cache');
    tokenRequest.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
    tokenRequest.send(WebUtils.getTokenEndpointData(webOptions, authorizationCode));
}}`

my two problems with this are that when I set pkceEnabled: true, I am not having the pkceCodeVerifier that is generated in buildWebOptions to verify the code and I get the following message => AADB2C90182: The supplied code_verifier does not match associated code_challenge

When I turn it off I get the message => AADB2C90205: This application does not have sufficient permissions against this web resource to perform the operation

But when it runs in a dialog it works.

Please help me I'm working now offer a Week on this.

Thanks in advance

Michael

atmike commented 1 year ago

For all that will have the same problem in the future. Whenever you set windowTarget to _self you have to set your responseType to token and turn off pkce. Then you get the token in the return URL and you can read it out hier noch einmal mein Einstellungen wie sie bei mit funktioniert haben:

getAzureInternalOAuth2Options(): OAuth2AuthenticateOptions {
    var tenantId = "6273e691-1111-2222-3333-e5267d5da3a6"; 
    var appId = "283a2967-1111-2222-3333-b249c0d72231";
    var redirectUrlWeb = "http://localhost:4200"; 
    return {
      appId: appId,
      authorizationBaseUrl: `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize`,
      scope: "api://283a2967-1111-2222-3333-b249c0d72231/tasks.read",
      accessTokenEndpoint: `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,
      resourceUrl: "https://graph.microsoft.com/v1.0/me/",
      responseType: "token",
      pkceEnabled: false,
      logsEnabled: true,
      web: {
        redirectUrl: redirectUrlWeb,
        windowTarget: "_self",
      },
      android: {
        redirectUrl: "msauth://{package-name}/{url-encoded-signature-hash}"
      },
      ios: {
        pkceEnabled: true, 
        redirectUrl: "msauth.{package-name}://auth"
      }
    };
  }

  getAzureB2COAuth2Options(): OAuth2AuthenticateOptions {
    var tenantId = "test"; 
    var appId = "066ed81b-1111-2222-3333-e5a54bc76fac";
    var redirectUrlWeb = "http://localhost:4200"; 
    var policyName: string = "B2C_1_susi";
    return {
      appId: appId,
      responseType: "token",
      authorizationBaseUrl: `https://${tenantId}.b2clogin.com/${tenantId}.onmicrosoft.com/${policyName}/oauth2/v2.0/authorize`,
      accessTokenEndpoint: `https:///${tenantId}.b2clogin.com/eisvogel2.onmicrosoft.com/${policyName}/oauth2/v2.0/token`,
      scope: `openid offline_access https://${tenantId}.onmicrosoft.com/tasks-armawin/tasks.read`, 
      resourceUrl: "https://graph.microsoft.com/v1.0/me/",
      pkceEnabled: false,
      logsEnabled: true,
      web: {
        redirectUrl: redirectUrlWeb,
        windowTarget: "_self",
      },
      android: {
        redirectUrl: "msauth://{package-name}/{url-encoded-signature-hash}" 
      },
      ios: {
        pkceEnabled: true, 
        redirectUrl: "msauth.{package-name}://auth"
      }
    };
  }