I have an MVC application that needs to access private API App in Azure that is protected with Azure AD authentication. So I need to get Azure AD bearer token, transfer it into Zumo-Auth
token and use it to access the API App.
I'm going through this tutorial and everything is working fine until the point when I need to request the token from authContext
. Here is the snippet of a code:
var authContext = new AuthenticationContext(
"https://login.microsoftonline.com/MyADDomain.onmicrosoft.com");
ClientCredential credential = new ClientCredential(
"04472E33-2638-FAKE-GUID-F826AF4928DB",
"OMYAPIKEY1x3BLAHEMMEHEHEHEHEeYSOMETHINGRc=");
// Get the AAD token.
var appIdUri =
"https://MyAppGateway-814485545465FAKE4d5a4532cd.azurewebsites.net/login/aad";
//var appIdUri = "https://MyADDomain.onmicrosoft.com/MyAppName";
//var appIdUri = "https://MyADDomain.onmicrosoft.com/";
//var appIdUri = "https://graph.windows.net";
AuthenticationResult result =
authContext.AcquireToken(appIdUri, credential); // <-- can't get the token from AD
// downhill from here
var aadToken = new JObject();
aadToken["access_token"] = result.AccessToken;
var appServiceClient = new AppServiceClient(
"https://MyAppGateway-814485545465FAKE4d5a4532cd.azurewebsites.net/");
// Send the AAD token to the gateway and get a Zumo token
var appServiceUser = await appServiceClient.LoginAsync("aad", aadToken);
The line with authContext.AcquireToken(appIdUri, credential)
is the one causing trouble.
If as appIdUri
I give https://MyAppGateway-814485545465FAKE4d5a4532cd.azurewebsites.net/login/aad
, I get exception:
400: AdalServiceException: AADSTS50001: Resource 'https://MyAppGateway-814485545465FAKE4d5a4532cd.azurewebsites.net/login/aad' is not registered for the account.
But this exact line is in the list of Reply Url
in the AD Application
When I try to use https://MyADDomain.onmicrosoft.com/MyAppName
or https://MyADDomain.onmicrosoft.com/
as appIdUri
I get a different exception message:
400: AdalServiceException: AADSTS50105: Application '04472E33-2638-FAKE-GUID-F826AF4928DB' is not assigned to a role for the application 'https://MyADDomain.onmicrosoft.com/MyAppName'
Or
400: AdalServiceException: AADSTS50105: Application '04472E33-2638-FAKE-GUID-F826AF4928DB' is not assigned to a role for the application 'https://MyADDomain.onmicrosoft.com/'
In both cases I had the App ID URI
in the AD Application set to 'https://MyADDomain.onmicrosoft.com/MyAppName' or 'https://MyADDomain.onmicrosoft.com/'. And both of the names in the list of Reply URL
.
Eventually after enough tries I have put https://graph.windows.net
as appIdUri
and got the bearer token back. But the token was given with expiry date in the past (about 1 minute in the past). So I could not do anything further with this. And got 401-Unauthenticated
when tried to use the token to login into API App.
What am I missing?
I have gone ahead and followed the tutorial to which you referred: Call an Azure API app from a web app client authenticated by Azure Active Directory
Then I was able to retrieve the token, and as you can see from the following demo, my code is no different than your code, except that it using a later version of the using Microsoft.IdentityModel.Clients.ActiveDirectory
libraries that use Async
.
class Program
{
static void Main(string[] args)
{
var authContext = new AuthenticationContext(Constants.AUTHORITY);
var credential =
new ClientCredential(Constants.CLIENT_ID, Constants.CLIENT_SECRET);
var result = (AuthenticationResult)authContext
.AcquireTokenAsync(Constants.API_ID_URL, credential)
.Result;
var token = result.AccessToken;
Console.WriteLine(token.ToString());
Console.ReadLine();
}
}
AUTHORITY
. The first segment of this is https://login.microsoftonline.com. The final segment is an allowed tenant. We set the allowed tenant at portal.azure.com, going to the Gateway for our application, and choosing Settings > Identity > Azure Active Directory > Allowed Tenants. My tenant is bigfontoutlook.onmicrosoft.com.
CLIENT_ID
. We retrieve this client id from the application that we added to Azure Active Directory. Find this at manage.windowsazure.com > Active Directory > Your Directory > APPLICATIONS > Your Application > CONFIGURE. Once we have retrieved it, we must add it to our Gateway's Azure Active Directory settings in the Client ID field.
CLIENT_SECRET
. We create/retrieve this in the same location that we retrieve our client id.
API_ID_URL
. We retrieve this within the Gateway blade for our Web API App by choosing Settings > Identity > Azure Active Directory > App URL.
Here are the ones that work for me.
class Constants
{
public const string AUTHORITY =
"https://login.microsoftonline.com/bigfontoutlook.onmicrosoft.com/";
public const string CLIENT_ID =
"0d7dce06-c3e3-441f-89a7-f828e210ff6d";
public const string CLIENT_SECRET =
"AtRMr+Rijrgod4b9Q34i/UILldyJ2VO6n2jswkcVNDs=";
public const string API_ID_URL =
"https://mvp201514929cfaaf694.azurewebsites.net/login/aad";
}
This is what the decoded JWT access token contains.
{
typ: "JWT",
alg: "RS256",
x5t: "MnC_VZcATfM5pOYiJHMba9goEKY",
kid: "MnC_VZcATfM5pOYiJHMba9goEKY"
}.
{
aud: "https://mvp201514929cfc350148cfa5c9b24a7daaf694.azurewebsites.net/login/aad",
iss: "https://sts.windows.net/0252f597-5d7e-4722-bafa-0b26f37dc14f/",
iat: 1442346927,
nbf: 1442346927,
exp: 1442350827,
ver: "1.0",
tid: "0252f597-5d7e-4722-bafa-0b26f37dc14f",
oid: "5a6f33eb-b622-4996-8a6a-600dce355389",
sub: "5a6f33eb-b622-4996-8a6a-600dce355389",
idp: "https://sts.windows.net/0252f597-5d7e-4722-bafa-0b26f37dc14f/",
appid: "0d7dce06-c3e3-441f-89a7-f828e210ff6d",
appidacr: "1"
}.
Note: It's a throwaway app in a throwaway active directory account with a throwaway resource group, so showing my security credentials is a non-issue.