Get access token for external api using Epicor's Azure AD in customization

Hi all,
Long time reader, first time poster.

I have a custom external API that authenticates with Azure AD. I’d like to use epicor’s azure ad implementation to get an access token for that api in an epicor customization. I can of course use a custom library, but I was thinking maybe I could avoid writing some custom code and use what epicor already has.

So I set up the app registrations and filled in the sysconfig variables, and I use this code to get an access token:

var token = Ice.Core.AzureActiveDirectory.GetAzureADToken(false);
var accessToken = Ice.Core.AzureActiveDirectory.GetAzureADAccessToken(token.AzureUser, false);

I do indeed get an access token this way, so that’s something! The problem is I can’t specify a scope, which I believe I would need to do to get a valid token for my API (e.g. api://external api client id/scope suffix). Inspecting the returned token the only scope it has is the “user_impersonation” scope that Epicor install guide adds to the epicor server app registration.

I also can’t seem to get a reference to a token service from inside epicor. I stumbled on the Ice.Core.AzureActiveDirectory looking through what was in the various dlls.

this is 10.2.500 on-prem, for reference

Maybe I’m going at this completely wrong! Any guidance would be appreciated, thanks!

1 Like

Epicor’s implementation of Azure AD Specifically only has that one scope and you cannot add or change them.
I think you need a different strategy here using Epicor’s Library though is not going to let you get an arbitrary token with an arbitrary scope from the customization

3 Likes

Hm, okay. It wasn’t completely out of left field, the plan would be to add the scope as a permission to the epicor client app registration. But I take your point.

I did manage to get a working token by replacing the AzureADWebAppID in the sysconfig with the custom web api client id. I’m sure that would have implications for signing into epicor, but we don’t use azure ad to sign into epicor, so it might be fine.

Any insight or resources about accessing epicor azure ad library functionality in customizations in general? Used my best googling and came up mostly empty.

Also, thanks for the reply!

If any future person wants to use this approach without overriding AzureADWebAppID, here is the code.
It’s basically just a custom ADAL with extra steps, though. The only advantage, if it can be called that, is using the static AuthorizationContext in the epicor session instead of creating your own.

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Reflection;

var webAppID = Ice.Lib.AppSettingsHandler.GetValue("MyCustomClientId", string.Empty);
var nativeClientAppID = Ice.Lib.AppSettingsHandler.GetValue("AzureADNativeClientAppID", string.Empty);	
var redirectURL = Ice.Lib.AppSettingsHandler.GetValue("AzureADRedirectUri", string.Empty);
var platformParameters = new PlatformParameters(PromptBehavior.Auto);
var authContext = (AuthenticationContext)typeof (Ice.Core.AzureActiveDirectory)
	.GetProperty("AuthContext", BindingFlags.NonPublic | BindingFlags.Static)
	.GetValue(null, null);

var result = authContext.AcquireTokenAsync(
	 webAppID,
	 nativeClientAppID,
	 new Uri(redirectURL),
	 platformParameters
	 ).Result;

var token = result == null ? string.Empty : result.AccessToken;

I added a custom appSettings entry (called MyCustomClientId) into the sysconfig with the external api’s client id.
For the record, I don’t recommend this approach to anyone.