简体   繁体   中英

Microsoft Graph API authentication error(Error Description: /me request is only valid with delegated authentication flow)

We have a console application that uses Aspose email dll for sending mails and various other functionalities.

Since it uses basic authentication that is getting deprecated soon by microsoft so we are planning to have authentication using Microsoft Graph API.

So I have done below steps

1)Registered the app in Microsoft Azure active directory and gave permissions under Microsoft Graph. PFA(AzureAPP_permissions.png)

2)I added code for generating token using graph API and then tried fetching email,sending email using Aspose dll but every time it throws below error.

**Aspose.Email.AsposeBadServerResponceException: 'Server error Status: BadRequest Description: /me request is only valid with delegated authentication flow. Details:

POST: https://graph.microsoft.com/v1.0/me/mailFolders/inbox/messages ---------------------------------------** Please help what is going wrong here PFB the code part

Graph_code

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Aspose.Email.Clients;
using Aspose.Email.Clients.Graph;
using Aspose.Email.Mapi;
using EASendMail;

namespace Email
{
    internal class Graph_API
    {
        private static string _clientId = ConfigurationManager.AppSettings["ClientId"];
        private static string _tenantId = ConfigurationManager.AppSettings["TenantId"];
        private static string _secretValue = ConfigurationManager.AppSettings["SecretValue"];
        
        static string _postString(string uri, string requestData)
        {
            HttpWebRequest httpRequest = WebRequest.Create(uri) as HttpWebRequest;
            httpRequest.Method = "POST";
           httpRequest.ContentType = "application/x-www-form-urlencoded";
          
            

            using (Stream requestStream = httpRequest.GetRequestStream())
            {
                byte[] requestBuffer = Encoding.UTF8.GetBytes(requestData);
                requestStream.Write(requestBuffer, 0, requestBuffer.Length);
                requestStream.Close();
            }

            try
            {
                HttpWebResponse httpResponse = httpRequest.GetResponse() as HttpWebResponse;
                var responseText = new StreamReader(httpResponse.GetResponseStream()).ReadToEnd();
                Console.WriteLine(responseText);
                return responseText;
               
            }
            catch (WebException ep)
            {
                if (ep.Status == WebExceptionStatus.ProtocolError)
                {
                    var responseText = new StreamReader(ep.Response.GetResponseStream()).ReadToEnd();
                    Console.WriteLine(responseText);
                }

                throw ep;
            }
        }

        public string GenerateToken()
          {
            
                string client_id = _clientId;
                string client_secret = _secretValue;

               
                string tenant = _tenantId;

                  
                          


                string requestData =
                string.Format("client_id={0}&client_secret={1}" + "&scope=https://graph.microsoft.com/.default&grant_type=client_credentials",
                client_id, client_secret);

                string tokenUri = string.Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", tenant);
               
               
                string responseText = _postString(tokenUri, requestData);

                OAuthResponseParser parser = new OAuthResponseParser();
                parser.Load(responseText);

            
            var vv = parser.AccessToken;
            return vv;

           
           
        }




        public void Generatemail()

        {

            interface_class bb = new interface_class();
            IGraphClient client = GraphClient.GetClient(bb, _tenantId);
            MapiMessage mm = new MapiMessage();
            mm.Subject = "EMAILNET-39318 " + Guid.NewGuid().ToString();
            mm.Body = "EMAILNET-39318 REST API v1.0 - Create Message";
            mm.SetProperty(KnownPropertyList.DisplayTo, "xxx@outlook.com");
            mm.SetProperty(KnownPropertyList.SenderName, "xxx@outlook.com");
            mm.SetProperty(KnownPropertyList.SentRepresentingEmailAddress, "xxx@outlook.com");

            // Create message in inbox folder
            MapiMessage createdMessage = client.CreateMessage(Aspose.Email.Clients.Graph.KnownFolders.Inbox, mm);

        }

        public void FetchMail()
        {
            try
            {
                interface_class bb = new interface_class();
               
                using (IGraphClient client = GraphClient.GetClient(bb, _tenantId))
                {
                    FolderInfoCollection folderInfoCol1 = client.ListFolders();
                    FolderInfo inbox = null;
                    foreach (FolderInfo folderInfo in folderInfoCol1)
                    {
                        if (folderInfo.DisplayName.Equals("Inbox", StringComparison.InvariantCultureIgnoreCase))
                        {
                            inbox = folderInfo;
                            break;
                        }
                    }
                    MessageInfoCollection messageInfoCol = client.ListMessages(inbox.ItemId);
                    MessageInfo messageInfo = messageInfoCol[0];
                    MapiMessage message = client.FetchMessage(messageInfo.ItemId);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            }

        }
    }

Itokenimplementor_class code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aspose.Email.Clients;
using Aspose.Email.Clients.Graph;

namespace Email
{
    internal class interface_class : ITokenProvider
    {
        Graph_API obj = new Graph_API();
        DateTime expirationDate = DateTime.Today.AddDays(1);
        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public OAuthToken GetAccessToken()
        {
            string token = obj.GenerateToken();

            return new OAuthToken(token, expirationDate);
        }

        public OAuthToken GetAccessToken(bool ignoreExistingToken)
        {
            throw new NotImplementedException();
        }
    }
}

https://graph.microsoft.com/v1.0/me/mailFolders/inbox/messages This endpoint is used to query inbox messages for a user right? Then who is /me here? And this is the issue.

In your code snippet, I noticed that you set the grant_type=client_credentials so you are using client credential flow. It's correct but pls note that you need to give application api permission. Application api permission is for client credential flow. And this api require Mail.ReadBasic.All, Mail.Read, Mail.ReadWrite permissions.

在此处输入图像描述

If you can generate access token successfully, you may decode the token the check if the roles claim contained correct permissions.

When you get a correct token, then pls use Get: /users/{id | userPrincipalName}/mailFolders/inbox/messages Get: /users/{id | userPrincipalName}/mailFolders/inbox/messages instead of /me . If you want to query emails for user1@yourtenant.onmicrosoft.com , then the url can be /users/user1@yourtenant.onmicrosoft.com/mailFolders/inbox/messages .

I also notice that you had GraphClient in your code. So you may also try my code below:

using Azure.Identity;
using Microsoft.Graph;

var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "your_tenant_name.onmicrosoft.com";
var clientId = "azure_ad_app_client_id";
var clientSecret = "client_secret_for_the_azuread_app";
var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var messages = await graphClient.Users["user_id/PrincipalName"].Messages
    .Request()
    .GetAsync();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM