microsoft graph可以使用验证码流程发送电子邮件吗

问题描述 投票:0回答:1

找到了有关使用 Microsoft graph 发送电子邮件的问题文章。在 Azure 上,我们注册了应用程序,并且添加了 Mail.Send 作为应用程序权限,如文章中所述,并且代码有效。但是,根据我的理解,该代码可以使用任何用户的电子邮件。我们想要使用身份验证代码流程,如下面的代码所示,因此我们有一个注册用户。然而,我们得到了禁止的回应。我们是否做错了什么,或者身份验证代码流程是否不适用于图形发送电子邮件。

    public static string ClientId = "ClientId Here";
    public static string TenantId = "TenantId Here";

    public static string RedirectUri = "http://localhost;

    public static string AppAuthority = $"https://login.microsoftonline.com/{TenantId}/v2.0";


        _clientApp = PublicClientApplicationBuilder.Create ( ClientId )
            .WithAuthority ( AppAuthority )
            .WithRedirectUri ( RedirectUri )
            .Build ();



        TokenCacheHelper.EnableSerialization ( _clientApp.UserTokenCache );


            // Set up the Microsoft Graph API endpoint and version
        string graphApiEndpoint = "https://graph.microsoft.com/v1.0";

        AuthenticationResult authResult = null;
        var app = _clientApp;

        List<string> scope = 
            new List<string> ()
            {
                "https://graph.microsoft.com/.default"
            };


        IAccount firstAccount;

        var accounts = await app.GetAccountsAsync ();
        firstAccount = accounts.FirstOrDefault ();

        try
        {
            authResult = await app.AcquireTokenSilent ( scope, firstAccount )
                .ExecuteAsync ();
        }
        catch ( MsalUiRequiredException ex )
        {
            try
            {
                authResult = await app.AcquireTokenInteractive ( scope )
                    .WithAccount ( firstAccount )
                    .WithPrompt ( Prompt.SelectAccount )
                    .ExecuteAsync ();
            }
            catch ( MsalException msalex )
            {}
        }
        catch ( Exception ex )
        {
            return;
        }

        if ( authResult == null )
            return;




        // Set up the user's email address and message content
        string userEmail = "[email protected]";
        string messageSubject = "Test email";
        string messageBody = "This is a test email sent via Microsoft Graph";


        // Set up the HTTP client and add the access token to the authorization header
        var httpClient = new HttpClient ();
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue ( "Bearer", authResult.AccessToken );

        // Set up the email message
        var emailMessage = new
        {
            message = new
            {
                subject = messageSubject,
                body = new
                {
                    contentType = "Text",
                    content = messageBody
                },
                toRecipients = new []
                {
                    new
                    {
                        emailAddress = new
                        {
                            address = userEmail
                        }
                    }
                }
            }
        };

        // Convert the email message to a JSON string and send the email via Microsoft Graph

        var options = new JsonSerializerOptions { WriteIndented = true };
        string jsonMessage = JsonSerializer.Serialize ( emailMessage, options );


        var response = await httpClient.PostAsync ( $"{graphApiEndpoint}/users/{userEmail}/sendMail", new StringContent ( jsonMessage, System.Text.Encoding.UTF8, "application/json" ) );

        if ( response.IsSuccessStatusCode )
        {
            Console.WriteLine ( "Email sent successfully." );
        }
        else
        {
            Console.WriteLine ( "Failed to send email. Status code: " + response.StatusCode );
        }



    using System;
    using System.IO;
    using System.Security.Cryptography;

    using Microsoft.Identity.Client;

    namespace WpfApp1
    {
        static class TokenCacheHelper
        {
            static TokenCacheHelper ()
            {
                try
                {
                    string folder = Environment.GetFolderPath ( Environment.SpecialFolder.ApplicationData );

                    // Combine the base folder with your specific folder....
                    string localFolder = Path.Combine ( folder, "Local" );

                    // CreateDirectory will check if every folder in path exists and, if not, create them.
                    // If all folders exist then CreateDirectory will do nothing.
                    Directory.CreateDirectory ( localFolder );

                    var localAppData = Environment.GetFolderPath ( Environment.SpecialFolder.LocalApplicationData );

                    // For packaged desktop apps (MSIX packages, also called desktop bridge) the executing assembly folder is read-only. 
                    // In that case we need to use Windows.Storage.ApplicationData.Current.LocalCacheFolder.Path + "\msalcache.bin" 
                    // which is a per-app read/write folder for packaged apps.
                    // See https://docs.microsoft.com/windows/msix/desktop/desktop-to-uwp-behind-the-scenes


                    CacheFilePath = Path.Combine ( localAppData, ".msalcache.bin3" );
                }
                catch ( System.InvalidOperationException )
                {
                    // Fall back for an unpackaged desktop app
                    CacheFilePath = System.Reflection.Assembly.GetExecutingAssembly ().Location + ".msalcache.bin3";
                }
            }

            /// <summary>
            /// Path to the token cache
            /// </summary>
            public static string CacheFilePath { get; private set; }

            private static readonly object FileLock = new object ();

            public static void BeforeAccessNotification ( TokenCacheNotificationArgs args )
            {
                lock ( FileLock )
                {
                    args.TokenCache.DeserializeMsalV3 ( File.Exists ( CacheFilePath )
                            ? ProtectedData.Unprotect ( File.ReadAllBytes ( CacheFilePath ),
                                                     null,
                                                     DataProtectionScope.CurrentUser )
                            : null );
                }
            }

            public static void AfterAccessNotification ( TokenCacheNotificationArgs args )
            {
                // if the access operation resulted in a cache update
                if ( args.HasStateChanged )
                {
                    lock ( FileLock )
                    {
                        // reflect changes in the persistent store
                        File.WriteAllBytes ( CacheFilePath,
                                           ProtectedData.Protect ( args.TokenCache.SerializeMsalV3 (),
                                                                 null,
                                                                 DataProtectionScope.CurrentUser )
                                          );
                    }
                }
            }

            internal static void EnableSerialization ( ITokenCache tokenCache )
            {
                tokenCache.SetBeforeAccess ( BeforeAccessNotification );
                tokenCache.SetAfterAccess ( AfterAccessNotification );
            }
        }
    }
azure email msal
1个回答
0
投票

注意:您可以通过授权码流程发送邮件。但此流程需要委派权限而不是应用程序权限。因此,向 Azure AD 应用程序授予

Mail.send
委派 API 权限。

创建 Azure Ad 应用程序并授予

Mail.send
委派 Api 权限:

enter image description here

现在我使用以下端点生成了auth-code

https://login.microsoftonline.com/TenantID/oauth2/v2.0/authorize?
&client_id=ClientID
&response_type=code
&redirect_uri=https://jwt.ms
&response_mode=query
&scope=https://graph.microsoft.com/.default
&state=12345

enter image description here

使用以下参数通过 Postman 生成访问令牌

https://login.microsoftonline.com/TenantID/oauth2/v2.0/token

client_id:ClientID  
scope:https://graph.microsoft.com/.default
grant_type:authorization_code  
code:code  
redirect_uri:https://jwt.ms
client_secret:Secret

enter image description here

确保解码访问令牌并检查范围是否显示:

enter image description here

现在通过使用上面的访问令牌,我能够成功发送邮件:

POST https://graph.microsoft.com/v1.0/me/sendMail
Content-type: application/json

{
  "message": {
    "subject": "Meet for lunch?",
    "body": {
      "contentType": "Text",
      "content": "The new cafeteria is open."
    },
    "toRecipients": [
      {
        "emailAddress": {
          "address": "xxx.onmicrosoft.com"
        }
      }
    ],
    "ccRecipients": [
      {
        "emailAddress": {
          "address": "xxx.onmicrosoft.com"
        }
      }
    ]
  },
  "saveToSentItems": "false"
}

enter image description here

参考:

用户:sendMail - Microsoft Graph v1.0 |微软

© www.soinside.com 2019 - 2024. All rights reserved.