Util.AzureCloud / Util.MSAL - can it create credentials for GraphServiceClient ?
I was blown away when I saw LinqPad's ability to simplify MSAL with MFA etc...
Truly great stuff, thanks !
I've tried to create a Graph client using the token generated and I just can't get it right.
Anyone know how I can feed a Util.MSAL token into new GraphServiceClient ?
Thanks
Paul
Comments
Have you tried the approach suggested in the LINQPad Tutorial and Reference?
Using a GraphServiceClient instead of an ArmClient:
Thanks Joe,
I'm missing something, I'm getting "Access is denied. Check credentials and try again." on the inner exception when using the graph client.
I think I need to set an App (with a client id) in Azure.
The outer exception is "Exception of type 'Microsoft.Graph.Models.ODataErrors.ODataError' was thrown."
After creating the graphServiceClient, I run.... this is where the access denied comes in
I'm using MFA, could that be the problem? The other example using Util.AzureCloud.PublicCloud works perfectly, but I can't seem to use that token for Microsoft Graph...
What happens when you try the code I posted?
Hi Joe,
It throws the exception I mentioned.
The outer exception is "Exception of type 'Microsoft.Graph.Models.ODataErrors.ODataError' was thrown."
Main error gives
I'm using your LINQPadTokenCredential class
My main method is almost identical to your example, adding the GraphServiceClient...
My credentials are good. I know this because if I use your example "Authentication with MSAL (interactive + MFA + Azure + OAuth).linq", and paste the token received into https://jwt.ms, I get a good response.
Are you confident that the config on the Azure end is set up correctly to allow these credentials?
No
I should have asked this question a different way, I still have a lot to learn about Azure AD, Auth and Graph
I can create a GraphServiceClient using a DeviceCodeCredential (Azure.Identity) and setting user scopes. To use this method I also need to register an App in Azure AD. This gives me a clientId and tenantId that I can use when instantiating the GraphServiceClient.
Using the LinqPad MSAL method, do I need to create the App in Azure Id, and how do I integrate the tenantId, clientId and scopes into the LinqPad MSAL method ?
My preference is to be able to access the Graph ".Me" methods (ie: userClient.Me.MailFolders["Inbox"].Messages) without needing to register an App in Azure AD, which is what I figured the LinqPad MSAL method gave me.
I found the time to come back to this on the weekend.
I wanted to authenticate with AzureAD and send an email using Microsoft Graph. I figured LinqPads new LINQPadTokenCredential would make this a breeze for me.
In the end, I resolved that what I was trying to do was impossible using the LINQPadTokenCredential method, so I used the traditional method.
Reasons Why:
Limited Scopes available from Util.AzureCloud.PublicCloud
I'm targeting a "Mail.Send" scope. It wasn't clear to me how I could create my own scope in Util.MSAL.AcquireTokenAsync. Using "Mail.Send", "https://graph.microsoft.com/.default" or a blank scope worked.
Needed to use a ClientId (AD App Regisgration)
I figured that I should be able to use LINQPadTokenCredential without having to create an App Registration in Azure AD. In the end, the easiest method was to create an App Registration, but there's no need for a secret using the method I used. It's sending as the logged user, not on behalf of the user.
**Set API Permissions, in the App Registration **
Mail.Send (from Microsoft Graph) must be set as in API Permission.
Needed a Redirect URL
Specify a redirect url, for LinqPad (or for a Desktop App), that's https://login.microsoftonline.com/common/oauth2/nativeclient
Thanks for the info.
You can specify scopes and a client ID in the Util.MSAL.AcquireTokenAsync method. Have you tried the following:
Thanks Joe,
Yes, that worked, and taught me a lot about MSAL in the process.
Paul
Suggestion: include the
LINQPadTokenCredential
class within LINQPad itself.I was able to get
GraphServiceClient
working with the providedLINQPadTokenCredential
class and a couple small modifications. Part of the trick was to update my app registration to have a callback ofhttps://login.microsoftonline.com/common/oauth2/nativeclient
This GitHub issue was helpful: https://github.com/microsoftgraph/msgraph-sdk-powershell/issues/2127
Manually modified the app manifest
Set the
Allow public client flows
toggle toYes
.Code
Thanks for the info.
The difficulty with including LINQPadTokenCredential in LINQPad is that it would need to be dynamically built in order to avoid creating a dependency on a specific version of Azure.Core. While this could be done with some automagic, it would get very messy if MS were to change the base class in the future, as LINQPad would need to figure out which version of Azure.Core you're referencing, and write a different version of LINQPadTokenCredential in each case.
It would also make it harder to diagnose and debug - right now, you can edit that class and set a breakpoint in GetTokenAsync to figure out exactly what's going on.