15
votes

I'm setting up authentication with Azure AD for an ASP.NET Web API 2 REST API. I'd like all clients to be able to use a username & password to authenticate with the REST API. I've setup Azure AD (full steps below, but essentially - created a directory, added a user, added an application, added roles to application in manifest, assigned user to application). However, when I try to test via a Console Application (full code at bottom), I get the exception:

An unhandled exception of type 'Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException' occurred in Microsoft.IdentityModel.Clients.ActiveDirectory.dll

Additional information: AADSTS50105: The signed in user '[email protected]' is not assigned to a role for the application '8ed6bbe9-dce7-4bed-83af-aa5472ac4eef'.

enter image description here

I'm guessing something needs to be tweaked in the Manifest, but I don't know.

Here is the code:

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

namespace WebApiClientTest
{
    class Program
    {
        static void Main(string[] args)
        {
            const string authorityUri = "https://login.microsoftonline.com/azureadwebapitest.onmicrosoft.com/";
            const string resource = "https://azureadwebapitest.onmicrosoft.com/test";
            const string clientId = "8ed6bbe9-dce7-4bed-83af-aa5472ac4eef";
            const string userId = "[email protected]";
            const string password = "[REMOVED for StackOverflow post]";

            UserCredential credentials = new UserCredential(userId, password);
            AuthenticationContext context = new AuthenticationContext(authorityUri);
            var authresult = context.AcquireToken(resource, clientId, credentials);
            Console.WriteLine("Access token: {0}", authresult.AccessToken);
            Console.ReadLine();
        }
    }
}

Full repro steps below:

1. Create new Azure AD Directory:

enter image description here

2. Add new Application:

enter image description here

enter image description here

3. Set "User assignment required to access app" to "YES". Set "Read directory data" application permissions. Copy client ID. Save:

enter image description here

4. Download manifest. Edit manifest and add two roles. Upload manifest:

enter image description here

enter image description here

5. Go back to directory from step 1 and Add User

enter image description here

enter image description here

enter image description here

6. Open new browser to https://account.activedirectory.windowsazure.com/ and sign in as user. Change password. Notice no applications available:

enter image description here

enter image description here

7. Go back to Classic Portal. Assign the user to the generalclient role in Application. Notice the user is now assigned to the application

enter image description here

enter image description here

enter image description here

8. Go back to user account portal and refresh. You might have to refresh a few times or click around. Notice the application is now shown

enter image description here

  1. It seems at this point, setup should be complete.

  2. Create a new console application.

  3. Install the Nuget package "Microsoft.IdentityModel.Clients.ActiveDirectory"

  4. Copy the code into the console application (top of post), insert your password into the "password" string, and Start Debugging:

Result:

An unhandled exception of type 'Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException' occurred in Microsoft.IdentityModel.Clients.ActiveDirectory.dll

Additional information: AADSTS50105: The signed in user '[email protected]' is not assigned to a role for the application '8ed6bbe9-dce7-4bed-83af-aa5472ac4eef'.

Expected Result:

The access token is written to the console output.

3
Can you change another role such as 'Global Admin' and try again ? And if you are using groups, avoid nested groups, try to use top-level groups.Alex Chen-WX
Thanks for the reply. Not using groups. Changed the user's "ORGANIZATIONAL ROLE" in the portal from "User" to "Global Admin", and still get the same exception. I also tried adding "Global Admin" and "GlobalAdmin" to "allowedMemberTypes" in the Manifest, but received an error when trying to upload with either value.BlueSky
you cant assess the webapi using clientid of the webapi, native app access webapi is a solutionLily_user4045
YOu are trying to access the web api from it's own client id. This is exactly what you don't need. You need to register a native client, give it access to the web api from the portal and use it's client id in your code.It's a trap
Did you work this issue out? I'm facing something similarDavid Thomas

3 Answers

3
votes

Worked for me :

Settings

Changing the property User assignment required? value to No worked for me. This can be found under Enterprise application --> Name of your registered application --> Properties ( Cheers 🍾)

1
votes

I had a similar issue for a different scenario. The reason was, the logged in user was not part of the application user list. This error got resolved as soon as I added that user in the Azure AD target application(The application you referring through the c# code). Also make sure the user is also part of a group.(If not create a group and just add the application users as members in that.)

-1
votes

If you have a Web API hosted in Azure and you want users to be able to user it then you need a token for that resource.

Roles will be advertised by the Web API Resource and not the Test. And once authenticated the resource access token will have roles in it that your Web API can then use to grant access.

Assuming this is NOT Multi-tenant

First you have to provision the Web API Resource and modify its manifest to support Roles. This is done by modifying appRoles key in the manifest. Then you need to update the manifest's oauth2Permissions to support delegated user access. Look here (Point 5) for information this https://azure.microsoft.com/en-us/documentation/articles/active-directory-application-manifest/

Now, that the Web API is ready, go to its configure tab and assign a any user lets call it UserXYZ to it for a particular role.

Next, provision a Native Client application in the same directory where the Web API is provisioned and in its configure Tab -> Add Application, select your Web API Resource and check box it for Delegated access.

Back in your Test Application do

 var uc = new UserCredential(userName, userPassword); // This is UserXYZ creds
 var context = new AuthenticationContext(...);  //Tenant Id must be correct
 result = context.AcquireToken("<Your Web API Resource App URI>", "<Your Native Client App Id>", uc);