问题
All the information I have found so far is that the desktop app needs to be registered with Microsoft Azure Active Directory, and that there is a library called ADAL that has all that is needed.
https://msdn.microsoft.com/en-nz/library/gg327838.aspx
https://docs.microsoft.com/en-nz/azure/active-directory/develop/active-directory-authentication-libraries
But what I want to do is just log into a third-party app that is already running on top of Dynamics, and then use a REST method to read custom data that this third-party app provides.
Is this at all possible?
If push comes to shove, I could write a C#.NET DCOM wrapper class that I then import into Delphi to gain access to the ADAL functionality, but the developers of the third-party Dynamics 365 app want to control access themselves.
I've looked at the RESTDemos project example supplied with Delphi Studio 10.2 Tokyo, and while it has a number of OAuth 2.0 examples (which is what Dynamics 365 needs), they don't include Dynamics 365 itself.
But to see what might be needed, I have created a test Google app, gone through the sign-in process for Google Tasks, was able to fetch the auth-code and access-token, and then fetch a list of tasks, so at least I know that the OAuth 2.0 mechanism I am supposed to use is working.
I have been given the CRM root service address, which I can log into using the credentials they provided, but that is just for the Dynamics 365 web application. I want to be able to use the same credentials to access the API of their app.
Edit:
If I append api/data/v8.0/ to the root URL they gave me, I can see a list of all the supported REST methods. Trying to use one, like api/data/v8.0/accounts/ gives me an "Access is denied" message unless I have actually logged into the CRM system via the Microsoft login page, at which point the REST method returns every account in the system.
Edit2:
From further investigations I have found that the method I am looking for is the one suggested for daemon/server applications.
https://docs.microsoft.com/en-nz/azure/active-directory/develop/active-directory-authentication-scenarios#daemon-or-server-application-to-web-api
For this to work, I do have to register the application but into the AD domain of the third-party Dynamics 365 app. Once this is done, I can create a Public Key that will allow me to get the Azure Token without needing to login as a particular Dynamics 365 User.
The code to use is similar to below:
RESTClient.BaseURL := 'https://login.microsoftonline.com/';
RESTRequest.Method := TRESTRequestMethod.rmPOST;
RESTRequest.Resource := '/' + ATenantID + '/oauth2/token';
RESTRequest.Params.AddItem('grant_type', 'client_credentials', TRESTRequestParameterKind.pkGETorPOST);
RESTRequest.Params.AddItem('client_id', AClientID, TRESTRequestParameterKind.pkGETorPOST);
RESTRequest.Params.AddItem('client_secret', AClientSecret, TRESTRequestParameterKind.pkGETorPOST);
RESTRequest.Params.AddItem('resource', AResourceURI, TRESTRequestParameterKind.pkGETorPOST);
RESTRequest.Execute;
The ATentantID, AClientID, AClientSecret, and AResourceURI values can all be obtained from Azure Active Directory; either from its properties, or the properties of the Registered app.
You then pull the Token from the RESTRequest.Response object.
回答1:
The following code using the Delphi REST Client Library will authenticate to Dynamics 365 when your application has been registered and configured correctly:
RESTClient.BaseURL := 'https://login.microsoftonline.com/';
RESTClient.Authenticator := OAuth2_Dynamics365;
RESTRequest.Method := TRESTRequestMethod.rmPOST;
RESTRequest.Resource := '/' + ATenantID + '/oauth2/token';
RESTRequest.Params.AddItem('grant_type', 'client_credentials', TRESTRequestParameterKind.pkGETorPOST);
RESTRequest.Params.AddItem('client_id', AClientID, TRESTRequestParameterKind.pkGETorPOST);
RESTRequest.Params.AddItem('client_secret', AClientSecret, TRESTRequestParameterKind.pkGETorPOST);
RESTRequest.Params.AddItem('resource', AResourceURI, TRESTRequestParameterKind.pkGETorPOST);
RESTRequest.Execute;
if RESTRequest.Response.GetSimpleValue('access_token', AToken) then
OAuth2_Dynamics365.AccessToken := AToken;
As noted above, the ATentantID, AClientID, AClientSecret, and AResourceURI values can all be obtained from Azure Active Directory; either from its properties, or the properties of the Registered app.
来源:https://stackoverflow.com/questions/49310503/how-to-connect-a-delphi-desktop-app-to-a-third-party-dynamics-365-app-using-oaut