web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics AX (Archived)

ODATA SERVICE Authentication Issue

(0) ShareShare
ReportReport
Posted on by

Hi ,

 I am new to AX and OData Service . One of my team mate has provided me link to AX Odata Service deployed on Azure Cloud .

He sent me the following details

1) Azure Login URL

2) Client Id

3) User Name and Password to access the AX OData Service

4) AX OData Service Base URL

Now I have written a simple C# Console Application to call the OData Service to get the list of Entities and then to get the values of an Entity using GET .

My Code looks like this 

*********************************************************************************************************

AuthenticationContext authenticationContext = new AuthenticationContext("<Azure Login URL>");


//To pass the user name and password without showing a pop - up, you can use the following overload of AcquireToken.
UserCredential userCred = new UserCredential("USERNAME", "PWD");
AuthenticationResult authenticationResult = authenticationContext.AcquireToken("AX Odata Service URL", "CLIENTID", userCred);


var settings = new ODataClientSettings("AX Odata Service URL");
settings.BeforeRequest = (message) =>
{
message.Headers.Add("Authorization",authenticationResult.CreateAuthorizationHeader());

};

ODataClient client = new ODataClient(settings);

model = client.GetMetadataAsync().ConfigureAwait(false).GetAwaiter().GetResult();

// Written getEntities method which will return all the Objects from the Odata Service URL

List<string> entities = getEntities(model).ToList();

// Now preparing the query to get the records from one of the entity .

var query = client.For("<Entity Name>");



var data = Task.Run(() => query.FindEntriesAsync()).ConfigureAwait(false).GetAwaiter().GetResult();

************************************************************************************

I am using Simple Odata Client to get the entities in the above example.

So using the above program I am able to connect and get the list of entities . But when I call the method

var data = Task.Run(() => query.FindEntriesAsync()).ConfigureAwait(false).GetAwaiter().GetResult();

I am getting 'Un Authorized' Error . I am not sure what I am doing wrong here . I am setting before the request the Authentication as well .

Could you guide me what is wrong (or) a simple code to get the query executed .

If there is any sample program which will read in the records for an Entity please point me to the correct URL .

If you need any more information please do let me know.

Thanks for your help and positive support.

Regards,

Sasi.

*This post is locked for comments

I have the same question (0)
  • Community Member Profile Picture
    on at

    Hi ,

    Can any one or an expert provide me some guidance or what i am doing wrong here.

     Thanks.

    Regards,

    Sasi.

  • Community Member Profile Picture
    on at

    Sasi,

    1) Ensure the native application registered in AAD, has been given permissions to Microsoft Dynamics ERP.  The application must be registered in an Azure tenant that has an AX 7 subscription.  

    Step by step instructions can be found here: ax.help.dynamics.com/.../dynamics-ax-7-services-technical-concepts-guide

    2) A live user must consent to the application the first time the client is called.  

    Add the following reference to your project: Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.  

    Change the AcuireToken() call to authenticationResult = authenticationContext.AcquireToken(<Base AX7 URL>, <ClientAppId>, new Uri(<redirect URI from client registration>));  

    A WinForm will pop up and asking the user to logon and consent to the web service client having permissions to AX.

    3) Reinstate the AcquireToken() call passing in user creds.  After the interactive user has consented to the application, the user creds can be used to authenticate silently.

    Example solutions can be found on GitHub github.com/.../Dynamics-AX-Integration

    Best Regards,

    Cody P

  • Community Member Profile Picture
    on at

    Hi ,

     Thanks for the details provided .

    Is it mandatory to login manually once ? My use case is : I am developing a c# class which I wanted to read data from Azure AX Odata Service and I wanted to pass in user credentials in the program . I dont want the user to login manually and then pass in the credentials .

    Is it not possible to silently send the credentials without any manual interaction . 

    Thanks one again for your inputs.

    Regards,

    Sasi.

  • Community Member Profile Picture
    on at

    Sasi,

    To be clear, after consent has been granted to the application, the web service client can authenticate silently with user creds.

    I have not found documentation on how long the user's consent is valid.

    If the application is registered in AAD by a global admin, the consent is implied and there is no need for interactive logon.

    In the field though, we may not be able to guarantee a global admin is the one registering the app.

    My team is preparing a separate WinForm app for the interactive logon and will include the consent as a step for admins.

    Best Regards,

    Cody P

  • Raphael Tagliani Profile Picture
    on at

    Dear Sasi,

    I'm struggling as well to call a custom web service on AX, without a prompt.

    As pointed out by Cody, this code works : github.com/.../Dynamics-AX-Integration (I tested it on Friday).

    Nevertheless, for me, it worked only using username/password credentials and ADAL version 2, and no prompt if the username/password is provided in a configuration file.

    In ADAL version 3, I had to generate a key, and register a webapp... the call to Azure is authenticated, but the client app is not liked to an identity in AX, apparently...

    ...still searching for a version that works with ADAL version 3 : if I make it work, I'll post the solution here.

  • Suggested answer
    Raphael Tagliani Profile Picture
    on at

    Dear Sasi,

    I finally got it working with ADAL version 3 : call to an OData endpoint, with a *native* application registered in Azure, using a username/pwd stored in a config file.

           public static async Task<string> GetAuthenticationHeader()

           {

               string aadTenant = WebServiceClientConfiguration.Settings.ActiveDirectoryTenant;

               string clientAppId = WebServiceClientConfiguration.Settings.ClientAppId;

               string clientKey = WebServiceClientConfiguration.Settings.ClientKey;

               string aadResource = WebServiceClientConfiguration.Settings.ActiveDirectoryResource;

               AuthenticationContext authenticationContext = new AuthenticationContext(aadTenant);

               ClientCredential clientCredential = new ClientCredential(clientAppId, clientKey);

               UserPasswordCredential upc = new UserPasswordCredential("taglr@mycompany.com", "MYPASSWORD"); // TODO move that in a configuration file

               // ADAL includes an in memory cache, so this call will only send a message to the server if the cached token is expired.

               AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(aadResource, clientAppId, upc);

               return authenticationResult.CreateAuthorizationHeader();

           }

    And the call to the method :

          static async Task ReadLegalEntities()

           {

               Uri oDataUri = new Uri(WebServiceClientConfiguration.Settings.ODataEntityPath, UriKind.Absolute);

               Resources axResources = new Resources(oDataUri);

               string authenticationHeader = await OAuthHelper.GetAuthenticationHeader();

               axResources.SendingRequest2 += new EventHandler<SendingRequest2EventArgs>(delegate (object sender, SendingRequest2EventArgs e)

               {

                   e.RequestMessage.SetHeader("Authorization", authenticationHeader);

               });

               Console.WriteLine();

               foreach (var legalEntity in axResources.LegalEntities.AsEnumerable())

               {

                   Console.WriteLine("Name: {0}", legalEntity.Name);

               }

               Console.ReadLine();

           }

    Finally, the call to the test method :

    ReadLegalEntities().Wait();

    If you want to encrypt the username/password in the config file, there is a way to do it.

    I guess that my solution is not the best there is : there should be a way to generate an authentication certificate, and to map it to a user in AX?

  • Community Member Profile Picture
    on at

    Hi Sasi ,

    i am also getting the same issue while authenticating. error is"The user or administrator has not consented to use the application with ID named Microsoft.ERP". Do you have any solution please provide.

    Thanks,

    Ravi

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics AX (Archived)

#1
Martin Dráb Profile Picture

Martin Dráb 4 Most Valuable Professional

#1
Priya_K Profile Picture

Priya_K 4

#3
MyDynamicsNAV Profile Picture

MyDynamicsNAV 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans