microsoftgraph / aspnetcore-connect-sample

[ARCHIVED] This ASP.NET Core MVC sample shows how to connect to Microsoft Graph using delegated permissions and the Azure AD v2.0 (MSAL) endpoint.
MIT License
123 stars 96 forks source link

How to add admin consent? #10

Closed Cowlephant closed 6 years ago

Cowlephant commented 6 years ago

I have tried so many things to try and modify this to acquire a token on behalf of the client only, and use Application level permissions to read mail. Every time I get Unauthorized access errors.

How do I implement admin consent into the flow for this?

mark-szabo commented 6 years ago

Hi @twilliamsgsnetx, to clarify: This sample is demonstrating the use of delegate-only permissions. Do you want to modify this app to use application permissions and request admin consent if not yet requested?

Can you please paste your current code what you are using now?

Cowlephant commented 6 years ago

I'm looking into insight on how to modify this application to use Application level permissions, so that it can accomplish both.. It wasn't until I started with it that I saw that it was for delegate-only permissions.

I can access profile information of the logged in user, which is great, but I cannot turn around and access the email of a user created specifically for my application, to manage the mailbox.

as a code example...

var graphClient = graph.GetAuthenticatedClient(identifier);
var messages = await graphClient.Users["abcdefg123-d402-4afc-abef-fakeguid3250"].MailFolders.Inbox.Messages.Request().Top(5).GetAsync();

Or perhaps you could point to another repository microsoftgraph that accomplishes this?

andrewbadera commented 6 years ago

Have you made your one-time call to the admin consent endpoint, as admin?

https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-scopes#using-the-admin-consent-endpoint

With your app ID as client_id, and I don't know that the redirect really matters here: https://login.microsoftonline.com/common/adminconsent?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&state=12345&redirect_uri=http://localhost/myapp/permissions

∞ Andy Badera

On Thu, Feb 8, 2018 at 11:16 AM, Tim Williams notifications@github.com wrote:

I have tried so many things to try and modify this to acquire a token on behalf of the client only, and use Application level permissions to read mail. Every time I get Unauthorized access errors.

How do I implement admin consent into the flow for this?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/microsoftgraph/aspnetcore-connect-sample/issues/10, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAzzNtxzMVETSKz794Tx-41nJOxPN0-ks5tSyvegaJpZM4R-t4y .

Cowlephant commented 6 years ago

Yes, I have done that.

Then I figured, okay, it's because I'm using AcquireTokenByAuthorizationCodeAsync instead of AcquireTokenForClientAsync

But I never can successfully call AcquireTokenForClientAsync because it throws errors for any scopes I try to use.

var client = new ConfidentialClientApplication(
                    azureOptions.ClientId,
                    $"{azureOptions.Instance}{azureOptions.TenantId}{azureOptions.GraphVersion}",
                    azureOptions.BaseUrl,
                    new ClientCredential(assertionCertificate),
                    null, null);

                var graphScopes = azureOptions.GraphScopes.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                var result = await client.AcquireTokenForClientAsync(graphScopes, false);

                var testGraphClient = new GraphServiceClient(new DelegateAuthenticationProvider(
                    requestMessage =>
                    {
                        var accessToken = result.AccessToken;

                        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                        return Task.CompletedTask;
                    }));

                var testMessages = await testGraphClient.Users["bcfake20-d402-4afc-abef-2effakeuser"].MailFolders.Inbox.Messages.Request().Top(5).GetAsync();
mark-szabo commented 6 years ago

Maybe you can have a look on this sample, but keep in mind, that this is ADAL (v1), not MSAL (v2): https://github.com/microsoftgraph/aspnetcore-apponlytoken-webhooks-sample

Cowlephant commented 6 years ago

I think I just solved it for myself. I tried all scope variations I could think of, except for https://graph.microsoft.com/.default

That was the missing link! I can now pull mail from other users who haven't been authenticated. I don't even need to perform admin consent first, it seems? Weird... but it's working now.

Now I just need to neatly encapsulate and clean up this code.

                var client = new ConfidentialClientApplication(
                    azureOptions.ClientId,
                    $"{azureOptions.Instance}{azureOptions.Domain}{azureOptions.GraphVersion}",
                    azureOptions.BaseUrl,
                    new ClientCredential(assertionCertificate),
                    null, null);

                var graphScopes = new string[] { "https://graph.microsoft.com/.default" };
                var result = await client.AcquireTokenForClientAsync(graphScopes, false);

                var testGraphClient = new GraphServiceClient(new DelegateAuthenticationProvider(
                    requestMessage =>
                    {
                        var accessToken = result.AccessToken;

                        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                        return Task.CompletedTask;
                    }));

                var testMessages = await testGraphClient.Users["somemail@companyname.org"].MailFolders.Inbox.Messages.Request().Top(5).GetAsync();
mark-szabo commented 6 years ago

Sure you needed, but you have already given that by calling the adminconsent endpoint before. :) Good to know that this was solved! 👍

Cowlephant commented 6 years ago

Yeah you're probably right on that. Where do I go to manage all those consents? Microsoft seems to have like 25 disjointed account management pages... spread across organizational and personal accounts. I've tried looking in portal.azure.com and apps.dev.microsoft.com

mark-szabo commented 6 years ago

You mean consent of the users in your AD? That can be checked on Azure Portal below your AD. Basically there are two, the old one for ADAL (on Azure portal) and the new one for MSAL (https://apps.dev.microsoft.com/), or? :)

mark-szabo commented 6 years ago

Closing question due to inactivity. Please reopen if you have anything to add!

Manik92 commented 6 years ago

Hi, I just want to know whether admin_consent can be used by default for admin and normal member users. Is there is a check once the admin signed using admin_consent the same will check for the members with admin consent url

mark-szabo commented 6 years ago

Hi @Manik92 admin_consent is a separate URL only to used once by the admin when giving consent. The check is whether users can sign in. If they get an error message saying an admin needs to give consent first, then it wasn't yet granted, but if they can sign in successfully, it was granted.

Manik92 commented 6 years ago

Thanks.

But I have one clarification.

Like user1 "John" is an admin user gives an access using admin_consent in oauth url. Then user (Stark) from the member of "John" (same tenant )is trying to login using admin_consent in oauth url, Whether stark can sign in successfully.