Authenticating Azure Service Management API with Azure AD User Credentials
There are two primary ways to authenticate against the Azure Service Management API:
- Azure Active Directory
- Management Certificate
In this post, we will see how to use the a user credential to authenticate against Azure Active Directory (Azure AD) and then query the Azure Service Management API. There are five steps to accomplish this task.
- Register an application with Azure AD
- Create a user in Azure AD
- Add the user as a co-administrator to the desired Azure subscription
- Obtain the authentication token
- Invoke the Azure Service Management API
1) Register an application with Azure AD
You will need to register a client application with Azure AD. You can find details on doing so at https://msdn.microsoft.com/en-us/library/azure/ee460782.aspx.
2) Create a user in Azure AD.
You will need to create a user in Azure AD if you don't already have one. Using the Azure Management Portal, navigate to your Azure AD directory and then proceed to the USERS section. Click the ADD USER button in the bottom command bar to start to add a new user. The user needs to be an Azure AD user, not a Microsoft account (i.e. not a hotmail.com, live.com, etc. account).
3) Add the user as a co-administrator
Adding the new (or existing) user as a co-administrator will allow the user access to the subscription. Until this point the user being set up is only authenticating against Azure AD, but is not authorized to work with the specific subscription. Again, using the Azure Management Portal, navigate to the SETTINGS section and then select ADMINISTRATORS from the top navigation area. Add the co-administrator by clicking on the ADD button in the bottom command bar and then completing the form to add the user. Be sure the user is a valid user in the Azure AD directory associated with the selected subscription.
4) Obtain the authentication token
The code to authenticate against Azure AD is actually pretty basic. You will need to use the Active Directory Authentication Library (ADAL) to help authenticate. ADAL can be obtained from NuGet. In this sample, ADAL version 3.0.110281957-alpha is used.
There are a few important things you will need:
- The Azure AD tenant ID
- The client ID that uniquely identifies the application created earlier.
See the MSDN page at https://msdn.microsoft.com/en-us/library/azure/ee460782.aspx for detailed screenshots on where to obtain these values.
The nice part about this code is that it can easily be used from a tool like LINQPAD, making it very quick and easy to reuse. For example, use the code via LINQPAD to get the authentication token and then your favorite REST API tool such as Fiddler or Postman to query the Azure Service Management API.
const string tenantId = "{YOUR-AZURE-AD_TENANT-ID}";
const string clientId = "{YOUR-AZURE-AD-APPLICATION-CLIENT-ID}";
var context = new AuthenticationContext(string.Format("https://login.windows.net/{0}", tenantId));
// TODO: Replace with your Azure AD user credentials (i.e. admin@contoso.onmicrosoft.com)
string user = "{YOUR-USERID]";
string pwd = "{YOUR-USER-PASSWORD}";
var userCred = new UserCredential(user, pwd);
AuthenticationResult result =
await context.AcquireTokenAsync("https://management.core.windows.net/", clientId, userCred);
var token = result.CreateAuthorizationHeader().Substring("Bearer ".Length);
Console.WriteLine("----");
// Dump() is a LINQPAD extension method. Use only with LINQPAD.
token.Dump();
5) Invoke the Service Management API
Now that you have the authentication token, you can use it to authenticate against the Azure Service Management API. As mentioned earlier, tools like Fiddler and Postman can be very helpful in quickly querying the API (especially if you don't need to use the results in another program, or are just curious as to what the API will return). When using one of those tools, you will need to set two important HTTP headers:
- Authorization - set this to "Bearer " and then the token received from the code above (it will be really long string)
- x-ms-version - this will vary depending on the operation you are invoking. See Service Management Versioning in MSDN for full details.
Now all that is left is to invoke the Service Management API. In the screenshot below, the operation being invoked is List Subscription Operations , which can be helpful in viewing many of the operations against a subscription (including those not shown in the Azure Management Portal's Operation Logs).
Comments
- Anonymous
March 18, 2016
I got the error "AADSTS90014: The request body must contain the following parameter: 'client_secret or client_assertion'."In case it helps anyone, I ended up doing this: var clientCredential = new ClientCredential(clientId, clientSecret); AuthenticationResult result = context.AcquireToken("https://management.core.windows.net/", clientCredential);where clientSecret is generated from the application registered with Azure AD in step 1 (configure > keys > add).- Anonymous
March 24, 2016
Thanks for pointing this out. My intent with the post was to show how to use the REST API without using a .NET library since, having gone there, I might as well use it to access resources instead of the REST API.
- Anonymous
- Anonymous
December 06, 2016
Hi. I have a working (daemon) app that authenticates to AAD using ADAL4J, and wish to add Azure support. I get a token when logging-in to https://management.core.windows.net/, but when I try to access anything in the subscription (e.g. listing available locations), I get:Caused by: com.microsoft.windowsazure.exception.ServiceException: ForbiddenError: The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription....in the current (new) portal, you cannot use certificates any longer (I don't want to anyway), and the subscriptions don't show in the old portal. Is this a case of having to now also define a service principal for the app? Seems odd, as I don't want to authenticate as a service principal, but as the AAD user, which is kind of the whole point of using AAD in the first place.Thanks...