Velvet Star Monitor

Standout celebrity highlights with iconic style.

general

How to login to a Azure Active Directory as a User in Test-Code?

Writer Olivia Zamora

I'm new to Azure and struggle a little in learning all the functionalities of the Azure Active Directory (AAD), so I hope you can clear some things up for me. Here is what I already did:

  • I registered a web app which serves as a resource provider and offers different APIs behind a API management service.

  • The web app has several users and roles in the AAD. Plus, more detailed permissions are set on App-Level. So the AAD doesn't control all permissions of my users.

  • Users are authenticated by using OAuth 2.0. In practice, this means if a new user tries to login to my app he gets redirected to Microsofts login page, enters username and password and then gets a JWT token from Microsofts authentication server.

Now what I want to do:

I want to write an app running on my build server which tests the user permissions. The app has to be written in C# .NET Core. Now I'm struggling on how to log in as a user from my code, so my question is:

How can i log in as a user from code to AAD and get the JWT token to test the user permissions? Can I do this by just using username / password, or do I need to register my test app in the AAD? What are the best solutions to reach my goals?

Thank you in advance

5

2 Answers

Juunas' comment already covered most of what is required. Just putting a bit more detail behind it.

  • You can use MSAL (link) to write a .NET Core application that accesses your API.
  • Within MSAL, you need to use username password authentication (Resource Owner Password Credentials grant) to acquire a JWT token. Please never use this grant outside your testing application.
  • Depending on how your app is configured, using just the clientId of the API could be enough. It would however be best practice to register a separate native app.

Some wording to help you along:

  • ClientId: The id of the client application which is requesting the token.
  • Scope: The scope of the API you acquire the token for. Should already be configured somewhere in your API. Usually something with the AppId URI. Possible examples could look like:
    • ...
  • Authority: Your AAD, e.g.

Code example for the password grant from the wiki (more examples there):

static async Task GetATokenForGraph()
{ string authority = ""; string[] scopes = new string[] { "user.read" }; PublicClientApplication app = new PublicClientApplication(clientId, authority); try { var securePassword = new SecureString(); foreach (char c in "dummy") // you should fetch the password securePassword.AppendChar(c); // keystroke by keystroke result = await app.AcquireTokenByUsernamePasswordAsync(scopes, "[email protected]", securePassword); } catch(MsalException) { // See details below } Console.WriteLine(result.Account.Username);
}
2

I actually find out a way to do it in "pure" C# without using the MSAL library, which I had some trouble with. So if you're looking for a solution w/o MSAL, you can do it the way described below.

Prerequisites

  • A user must exist in the AAD and must not use a Microsoft Account (source in Active Directory must not be "Microsoft Account").
  • A client application must be registered in the Azure Active Directory. The client app must be granted permissions to the app you want to test. If the client app is of type "Native", no client secret must be provided. If the client app is of type "Web app / api", a client secret must be provided. For testing purposes, its recommended to use an app of type "Native" without a client secret.

  • There must be no two factor authentication.

C# Code

You can than create a class "JwtFetcher" and use code like this:

 public JwtFetcher(string tenantId, string clientId, string resource) { this.tenantId = !string.IsNullOrEmpty(tenantId) ? tenantId : throw new ArgumentNullException(nameof(tenantId)); this.clientId = !string.IsNullOrEmpty(clientId) ? clientId : throw new ArgumentNullException(nameof(clientId)); this.resource = !string.IsNullOrEmpty(resource) ? resource : throw new ArgumentNullException(nameof(resource)); } public async Task<string> GetAccessTokenAsync(string username, string password) { var requestContent = this.GetRequestContent(username, password); var client = new HttpClient { BaseAddress = new Uri(ApplicationConstant.Endpoint.BaseUrl) }; var message = await client.PostAsync(this.tenantId + "/oauth2/token", requestContent).ConfigureAwait(false); message.EnsureSuccessStatusCode(); var jsonResult = await message.Content.ReadAsStringAsync().ConfigureAwait(false); dynamic objectResult = JsonConvert.DeserializeObject(jsonResult); return objectResult.access_token.Value; } private FormUrlEncodedContent GetRequestContent(string username, string password) { List<KeyValuePair<string, string>> requestParameters = new List<KeyValuePair<string, string>>() { new KeyValuePair<string, string>(ApplicationConstant.RequestParameterName.GrantType, ApplicationConstant.RequestParameterValue.GrantTypePassword), new KeyValuePair<string, string>(ApplicationConstant.RequestParameterName.Username, username), new KeyValuePair<string, string>(ApplicationConstant.RequestParameterName.Password, password), new KeyValuePair<string, string>(ApplicationConstant.RequestParameterName.ClientId, this.clientId), new KeyValuePair<string, string>(ApplicationConstant.RequestParameterName.Resource, this.resource) }; var httpContent = new FormUrlEncodedContent(requestParameters); return httpContent; }

The grant type for this is just "password".

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.