Skip to content
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

Error when authenticating: Ws-Trust #118

Closed
ojoven opened this issue Apr 5, 2022 · 22 comments
Closed

Error when authenticating: Ws-Trust #118

ojoven opened this issue Apr 5, 2022 · 22 comments

Comments

@ojoven
Copy link

ojoven commented Apr 5, 2022

Hi,

I wanted to inform you that the SDK is not working anymore.

When trying to connect via

$options = [
	'serverUrl' => 'https://' . $domain . '.crm3.dynamics.com',
	'username' => $username,
	'password' => $password,
	'authMode' => 'OnlineFederation',
];

$serviceSettings = new Settings($options);
$service = new OrganizationService($serviceSettings);

The client throws an error with the following message:

An error occurred when processing the security tokens in the message:You are using Ws-Trust authentication which has been deprecated and no longer supported in your environment. Please use OAuth2.0 authentication and refer https://aka.ms/dvwsdep.

Microsoft offers some documentation on how to fix this:
https://docs.microsoft.com/en-us/power-apps/developer/data-platform/authenticate-office365-deprecation

Is this something you already fixed in your premium package? I don't see it in the Premium Features, but I'd understand that this was already fixed on it. Could you please confirm?

Thanks

@georged
Copy link
Contributor

georged commented Apr 5, 2022

@ojoven toolkit does support OAuth as of commit 6dd4aca

$options = [
	'serverUrl' => 'https://' . $domain . '.crm3.dynamics.com',
	'applicationId' => $applicationId,
	'clientSecret' => $secret,
	'authMode' => 'OnlineFederation',
	'authMethod' => 'sharedSecretAuth',
        'cache' => new AlexaCRM\CRMToolkit\NullCache(),
];
$serviceSettings = new OnlineS2SSecretAuthenticationSettings($options);

@georged georged closed this as completed Apr 5, 2022
@ojoven
Copy link
Author

ojoven commented Apr 5, 2022

Hey @georged

That's great, I saw that there was a change some months ago to adapt the SDK to OAuth.

I was going to ask you how to build the settings with the new data but I saw that you edited the comment with the solution.

I'm having some issues yet with OnlineS2SAuth.php
Uncaught Error: Call to a member function get() on null in /alexacrm/php-crm-toolkit/src/Auth/OnlineS2SAuth.php:49

But it may be cache related.
Please let me test a bit further and I'll get back to you with the outcome.

Thanks again.

@georged
Copy link
Contributor

georged commented Apr 5, 2022

@ojoven you do need cache instance. You could use NullCache I suppose but then you'll be facing token request every time so it'd be better if you use a proper one. I updated sample with the null cache - try it.

@ojoven
Copy link
Author

ojoven commented Apr 5, 2022

Hey @georged

After adding the NullCache, the connection was successfully made.

However, when retrieving doing a request to retrieve data:

$registryResult = $service->retrieveMultiple($query, false);

We're getting an error:

Uncaught Exception: Could not find RetrieveMultipleResponse node in XML provided in /alexacrm/php-crm-toolkit/src/Client.php:1620

After investigating, the XML was returning:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode>s:Client</faultcode><faultstring xml:lang="en-US">Principal user (Id=XXXXXXXXXXXXXXXX, type=8, roleCount=1, privilegeCount=793, accessMode=4), is missing prvReadadoxio_licencetype privilege (Id=XXXXXXXXXXXXXXXX) on OTC=XXXXXXXXXXXX for entity 'adoxio_licencetype' (LocalizedName='Licence Type'). context.Caller=XXXXXXXXXXXXXXXXXXXX</faultstring><detail>...

So for this, it looks like we need to check with our client so they give the necessary permissions to that user.

I just want to ask you a final thing.

Instead of using NullCache, I assume that we need to implement our own Cache, is that correct?

Thanks so much for all your support.

@georged
Copy link
Contributor

georged commented Apr 5, 2022

The message is about insufficient privileges for the app user. If you have working code when username was used, assign the same roles to the app user.

You most certainly don't need to roll out your own cache implementation. We expect PSR-16 compliant cache (https://www.php-fig.org/psr/psr-16/) - there are plenty of those around.

@georged
Copy link
Contributor

georged commented Apr 5, 2022

Last but not least @ojoven. Take a look at https://github.com/AlexaCRM/dynamics-webapi-toolkit - it's web api based and much more robust than the current SOAP based toolkit. That's the recommended way forward.

@ojoven
Copy link
Author

ojoven commented Apr 5, 2022

Hey @georged

This is perfect. Thanks so much.

Yes, some specific requests are made with the WebAPI - that's why we already had the applicationId and secret - but we initially started with SOAP due to some restrictions and migrating may not be straightforward, though we'll totally consider it.

Thanks for your support.

@dantedantas
Copy link

Hey @georged

That's great, I saw that there was a change some months ago to adapt the SDK to OAuth.

I was going to ask you how to build the settings with the new data but I saw that you edited the comment with the solution.

I'm having some issues yet with OnlineS2SAuth.php Uncaught Error: Call to a member function get() on null in /alexacrm/php-crm-toolkit/src/Auth/OnlineS2SAuth.php:49

But it may be cache related. Please let me test a bit further and I'll get back to you with the outcome.

Thanks again.

Hi @ojoven ,
I have the same issue as you. Please, could you help me no how could I solve this issue?
Could you share with me which changes have you done and where?

Thank you.

Dante

@ojoven
Copy link
Author

ojoven commented Apr 6, 2022

Hey @dantedantas

Sorry for the delay in my response.

As georged commented, you need to add a cache to the options array:
#118 (comment)

'cache' => new AlexaCRM\CRMToolkit\NullCache(),

This NullCache, however, is a dummy cache and won't store your request tokens and so, the requests will be very consuming.
However, it can work for an initial approach of checking if this works or not.

Once you check that it works, it's time to use a real cache.

In our case, we used FileSystem:
https://github.com/php-cache/filesystem-adapter

You have others (Memcached, Redis, etc. here: https://github.com/php-cache)

So our code looked like this:

$filesystemAdapter = new Local(__DIR__ . '/');
$filesystem = new Filesystem($filesystemAdapter);

$options = [
...your options here
'cache' => new Cache\Adapter\Filesystem\FilesystemCachePool($filesystem)
];

Hope this helps!

Cheers,
Mikel

@dantedantas
Copy link

dantedantas commented Apr 7, 2022

Hola @ojoven , buenas tardes.
Thank you for your feedback.

I have no idea why I am not able to implement the changes. I am getting am error.

`Notice: Undefined property: AlexaCRM\CRMToolkit\Settings::$applicationId in C:\Tools\xampp\htdocs\incidentreport\vendor\alexacrm\php-crm-toolkit\src\Client.php on line 1467

AlexaCRM\CRMToolkit\Client requires Application ID and Client Secret`

image

Maybe the AppID was created wrong?

Thank you/Gracias,
Dante

@georged
Copy link
Contributor

georged commented Apr 7, 2022

@dantedantas what object you're instantiating for settings? It should be OnlineS2SSecretAuthenticationSettings not Settings. Also, username and password are obviously no longer used and not required. The code should be like this:

$options = [
	'serverUrl' => 'https://instance.crmN.dynamics.com',
	'applicationId' => $applicationId,
	'clientSecret' => $secret,
	'authMode' => 'OnlineFederation',
	'authMethod' => 'sharedSecretAuth',
        'cache' => new AlexaCRM\CRMToolkit\NullCache(),
];
$serviceSettings = new OnlineS2SSecretAuthenticationSettings($options);

@Nasiralijames
Copy link

Nasiralijames commented Apr 8, 2022

Hey @dantedantas

Sorry for the delay in my response.

As georged commented, you need to add a cache to the options array: #118 (comment)

'cache' => new AlexaCRM\CRMToolkit\NullCache(),

This NullCache, however, is a dummy cache and won't store your request tokens and so, the requests will be very consuming. However, it can work for an initial approach of checking if this works or not.

Once you check that it works, it's time to use a real cache.

In our case, we used FileSystem: https://github.com/php-cache/filesystem-adapter

You have others (Memcached, Redis, etc. here: https://github.com/php-cache)

So our code looked like this:

$filesystemAdapter = new Local(DIR . '/'); $filesystem = new Filesystem($filesystemAdapter);

$options = [ ...your options here 'cache' => new Cache\Adapter\Filesystem\FilesystemCachePool($filesystem) ];

Hope this helps!

Cheers, Mikel

Hi @ojoven,
We have followed the given procedure for using the Filesystem from the GitHub - https://github.com/php-cache/filesystem-adapter

But we are getting the below Fatal error.

Could you please check and guide us for the same.

Fatal error: Uncaught Error: Class 'League\Flysystem\Adapter\Local' not found in C:\xampp\htdocs\sdg\wp-content\themes\edubiz_child\functions\synchronize-wordpress-dynamics\syn_contact_enquiry.php:112

By using NullCache we can able to create a successful connection. But while using the Filesystem facing the above error.
We have placed all the folders and files at proper place.

Thanks!

@ojoven
Copy link
Author

ojoven commented Apr 8, 2022

Hey @Nasiralijames

Do you have the following in your code:

require_once __DIR__ . '/../vendor/autoload.php';

and

use League\Flysystem\Adapter\Local;
use League\Flysystem\Filesystem;

at the top of your file?

It looks like you may be missing the vendor autoload?
Or that you have it in some way that it's not retrieving correctly the classes from those files.

Without seeing the full file I can't say.

Cheers

@georged georged mentioned this issue Apr 9, 2022
@Nasiralijames
Copy link

Hey @Nasiralijames

Do you have the following in your code:

require_once __DIR__ . '/../vendor/autoload.php';

and

use League\Flysystem\Adapter\Local;
use League\Flysystem\Filesystem;

at the top of your file?

It looks like you may be missing the vendor autoload? Or that you have it in some way that it's not retrieving correctly the classes from those files.

Without seeing the full file I can't say.

Cheers

Hi @ojoven,

Sorry for the delay in my response.

Thanks for the help I have added the above given line of code now and it is working fine.

Thanks a lot for your guidance and help.

Regards,
Nasir

@janeliasprague
Copy link

Hi guys!

What did I do wrongly if I'm getting this notice "Undefined index: WWW-Authenticate"? (see screenshot bellow)

I created single tenant application at admin.microsoft.com according to this article https://docs.microsoft.com/en-us/power-apps/developer/data-platform/use-single-tenant-server-server-authentication#register-your-application-on-azure-ad

I am using application ID and client secret in my code.

Snímek obrazovky 2022-07-10 v 16 06 16

@georged
Copy link
Contributor

georged commented Jul 10, 2022

Check your instance URL - does not look it's a valid one. Also, drop /api/data/v9.0/ part, just use https://yourorg.crm4.dynamics.com

@janeliasprague
Copy link

This is my service settings

$this->options = [
            'serverUrl' => "https://myorg.crm4.dynamics.com",
            'applicationId' => self::APPID,
            'clientSecret' => self::CLIENTSECRET,
            'authMode' => 'OnlineFederation',
            'authMethod' => 'sharedSecretAuth',
            'cache' => new \AlexaCRM\CRMToolkit\NullCache(),
];

$serviceSettings = new OnlineS2SSecretAuthenticationSettings($this->options);

That part /api/data/v9.0/ was added automatically.

@georged
Copy link
Contributor

georged commented Jul 11, 2022

@janeliasprague try again because yesterday the url was not valid (perhaps transient provisioning issue).
If you're still getting an error, add a logger to get more information about what's coming back.

@janeliasprague
Copy link

I'm still getting a notice (it is not an error). I can skip this notice and I get cURL error.
Snímek obrazovky 2022-07-11 v 12 26 40

What do you mean by "add a logger"? How can I do it? Thanks

@georged
Copy link
Contributor

georged commented Jul 11, 2022

AbstractSettings class contains $logger member that you can set to a PSR-3 compliant logger and get extended error details.

use Monolog\Logger;
...
$client = new OrganizationService($clientSettings);
$client->logger = new \Monolog\Logger( 'whatever' );

@janeliasprague
Copy link

function detectTenantID() returns array $headers and then is looking for "WWW-Authenticate" field. But the field is called "www-authenticate".

The question is - do I have the right version of the library?

I've installed it using
composer update alexacrm/php-crm-toolkit:dev-master#6dd4aca --with-dependencies

Snímek obrazovky 2022-07-11 v 14 04 52

Snímek obrazovky 2022-07-11 v 14 09 13

@georged
Copy link
Contributor

georged commented Jul 11, 2022

If you just started I really recommend you switch to https://github.com/AlexaCRM/dynamics-webapi-toolkit instead. Latter is based on Web API and is the primary toolkit moving forward.

As per Readme

This toolkit supports only Dynamics 365 SOAP interface. For PHP implementation of the Dynamics 365 Web API, see dynamics-webapi-toolkit project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants