0

I would like to check User's Active Directory groups and assign roles based on them every time when user logs in to my application via Azure Active Directory OAuth. My app is running Orchard Core so I though to make it using Orchard's builtin AAD Authentication Module.

I couldn't make it using any configuration so I've copied the source code of entire module into my application (that uses Orchard as a NuGet package) and modified the OpenIdConnct configuration manually to add an event listener when token is issued and then make a call to Microsoft Graph API to retrieve groups information.

The problem is that the token I receive looks to be valid (I've checked on jwt.io and the scope in token is: "scp": "offline_access openid profile User.Read"). But when I try to use this token in Graph API it responds with Access Token missing or malformed..

I've spent a lot of time and have no idea why it happens.

The code I use is the following:

options.ClientId = azureADOptions.ClientId;
options.ClientSecret = azureADOptions.ClientSecret;
options.Authority = new Uri(new Uri(azureADOptions.Instance), azureADOptions.TenantId).ToString();
options.CallbackPath = azureADOptions.CallbackPath ?? options.CallbackPath;
options.SignedOutCallbackPath = azureADOptions.SignedOutCallbackPath ?? options.SignedOutCallbackPath;
options.SignInScheme = "Identity.External";

options.Scope.Add("openid");
options.Scope.Add("offline_access");
options.Scope.Add($"api://{azureADOptions.ClientId}");

options.Resource = azureADOptions.ClientId;
options.Scope.Add(HttpUtility.HtmlEncode(GraphService.GraphInstance));
options.ResponseType = OpenIdConnectResponseType.IdTokenToken;

options.Events.OnMessageReceived += context =>
        {
            return Task.CompletedTask;
        };

options.Events.OnTokenResponseReceived += context =>
        {
            return Task.CompletedTask;
        };

options.Events.OnTicketReceived += context =>
        {
            return Task.CompletedTask;
        };

I've read the access token in the events handlers and used postman to make a call to Graph API and it failed.

What's the problem?

1
  • If my answer is helpful for you, you can accept it as answer( click on the check mark beside the answer to toggle it from greyed out to filled in.). See meta.stackexchange.com/questions/5234/…. This can be beneficial to other community members. Thank you. Commented Jun 8, 2020 at 10:10

2 Answers 2

1

You don't need to call the Microsoft Graph API to retrieve group information. You just need to modify the "groupMembershipClaims" field in application manifest reference here:

"groupMembershipClaims": "SecurityGroup"

enter image description here

Then the token will contain the Ids of the groups that the use belongs to like below :

{ "groups": ["93d96b98-cc9b-410e-a5c8-105883edexxx"] }

Then you can find users based on group id in the code.

You can also define some application roles and assign roles to groups. Then, the users in the group will have the following claims:

{ "roles": ["admin"] }

Then you can implement your authorization logic based on the roles of the user.

For more details, please refer to:https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-add-app-roles-in-azure-ad-apps.

Update:

Because the token can only contain up to 200 groups, using this method requires that your users belong to less than 200 groups.

Sign up to request clarification or add additional context in comments.

3 Comments

Do note that there is a maximum limit to groups that are included in the token. If a user has IIRC more than 200 groups, no groups will be in the token and they must instead be queried from MS Graph API.
@juunas Thanks for your addition, you are right, I will update my answer.
Thanks, I also figured it out after many hours but didn't know about the limitation. But still, I'm wondering why access token didn't work?
0

I'm not too familiar with orchard, but are you sure that you are getting the access token and not the id token? from what i can see it looks like you may be getting an id token instead.. which would explain the failure, you need an access token with scopes to access graph.

1 Comment

Yes, the options.ResponseType = OpenIdConnectResponseType.IdTokenToken; option configures it, I am getting both Id And Access tokens. Both are valid (checked on jwt.io) but none of them can be used for Graph authorization.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.