oauth2.0 使用Microsoft Graph代表用户发送电子邮件所需的权限是什么?

4dc9hkyq  于 2023-04-29  发布在  其他
关注(0)|答案(2)|浏览(252)

几天来,我一直在努力实现一个功能,用户可以使用他们的outlook电子邮件进行身份验证,并安排发送电子邮件。因此,API应该能够代表经过身份验证的用户发送电子邮件。
身份验证流程正常工作,我能够保存访问令牌。Graphme调用也按预期工作。我用用户数据得到了预期的响应。
问题是当我试图发送电子邮件时。我得到以下错误:

{"statusCode":401,"code":null,"requestId":null,"date":"2023-04-21T14:18:46.748Z","body":{"_writeState":{"0":0,"1":0},"_readableState":{"objectMode":false,"highWaterMark":16384,"buffer":{"head":null,"tail":null,"length":0},"length":0,"pipes":null,"pipesCount":0,"flowing":null,"ended":false,"endEmitted":false,"reading":false,"sync":false,"needReadable":false,"emittedReadable":false,"readableListening":false,"resumeScheduled":false,"emitClose":true,"autoDestroy":false,"destroyed":false,"defaultEncoding":"utf8","awaitDrainWriters":null,"multiAwaitDrain":false,"readingMore":false,"decoder":null,"encoding":null},"readable":true,"_events":{"error":[null,null]},"_eventsCount":6,"_writableState":{"objectMode":false,"highWaterMark":16384,"finalCalled":false,"needDrain":false,"ending":false,"ended":false,"finished":false,"destroyed":false,"decodeStrings":true,"defaultEncoding":"utf8","length":10,"writing":true,"corked":0,"sync":false,"bufferProcessing":false,"writelen":10,"afterWriteTickInfo":null,"bufferedRequest":null,"lastBufferedRequest":null,"pendingcb":1,"prefinished":false,"errorEmitted":false,"emitClose":true,"autoDestroy":false,"bufferedRequestCount":0,"corkedRequestsFree":{"next":null,"entry":null}},"writable":true,"allowHalfOpen":true,"_transformState":{"needTransform":false,"transforming":true,"writechunk":{"type":"Buffer","data":[31,139,8,0,0,0,0,0,4,10]},"writeencoding":"buffer"},"_hadError":false,"bytesWritten":0,"_handle":{"buffer":{"type":"Buffer","data":[31,139,8,0,0,0,0,0,4,10]},"availOutBefore":16384,"availInBefore":10,"inOff":0,"flushFlag":2},"_outBuffer":{"type":"Buffer","data":[85,85,85,85,85,85,80,0,0,0,0,0,0,0]},"_outOffset":0,"_chunkSize":16384,"_defaultFlushFlag":2,"_finishFlushFlag":2,"_defaultFullFlushFlag":3,"_maxOutputLength":2147483647,"_level":-1,"_strategy":0}}

我认为我没有使用正确的权限,但我已经尝试了许多(所有注解的权限),仍然得到相同的错误消息。我别无选择了。
你们知道这里可能会出什么问题吗?
先谢谢你了
我使用了以下代码来验证用户并发送电子邮件:

import * as msal from "@azure/msal-node";
import { Client } from "@microsoft/microsoft-graph-client";

export const msalConfig: msal.Configuration = {
  auth: {
    clientId: “CLIENT_ID”,
    authority: "https://login.microsoftonline.com/TENENT_ID”,
    clientSecret: “CLIENT_SECRET”,
  },
};

export const cca = new msal.ConfidentialClientApplication(msalConfig);

export const getGraphClient = (accessToken: string | null) => {
  const graphClient = Client.init({
    authProvider: (done) => {
      done(null, accessToken);
    },
  });
  return graphClient;
};

export const protectedResources = {
  graphMe: {
    meEndpoint: "https://graph.microsoft.com/v1.0/me",
    usersEndpoint: "https://graph.microsoft.com/v1.0/users/",
    scopes: [
      "openid",
      "profile",
      "user.read",
      "mail.send",
      "offline_access",
      //  "Mail.Send",
      //  "https://graph.microsoft.com/.default",
      //  "https://graph.microsoft.com/Mail.Send.Shared",
      //  "https://graph.microsoft.com/Mail.Read",
      //  "https://graph.microsoft.com/profile",
      //  "https://graph.microsoft.com/.default",
      //  "https://outlook.office.com/IMAP.AccessAsUser.All",
    ],
  },
};
// Code to start the authentication flow
const state = request.query.state as string;

try {
    // Get the authorization URL
    const authCodeUrlParameters: msal.AuthorizationUrlRequest = {
        scopes: protectedResources.graphMe.scopes,
        redirectUri: "https://example.com/outlookOauth2Callback",
        codeChallengeMethod: "S256",
        state: state,
    };
    const authorizeUrl = await cca.getAuthCodeUrl(authCodeUrlParameters);
    response.redirect(authorizeUrl);
    return;
} catch (error) {
    console.log(error);
    response.status(500).send(error);
    return;
}
// Code to get the access Token
const code = request.query.code as string;
const state = request.query.state as string;

try {
    const tokenRequest: msal.AuthorizationCodeRequest = {
        code: code,
        scopes: protectedResources.graphMe.scopes,
        redirectUri:
        "https://example.com/outlookOauth2Callback",
        codeVerifier: request.query.code_verifier as string,
    };

    const accessToken = await cca.acquireTokenByCode(tokenRequest);
    await saveUserToken(code, accessToken);
    console.log("Successfully authorized");

   response.redirect("https://example.com/callback.html?code=" + code + "&state=" + state);
     return;
} catch (error) {
    console.log(error);
    response.status(500).send(error);
    return;
}
// Code to send the email
const graphUser = await getGraphClient(token.accessToken)
      .api(protectedResources.graphMe.meEndpoint)
      .get();

functions.logger.log("Graph User: " + JSON.stringify(graphUser));

const message = {
      subject: subject,
      body: {
        contentType: "HTML",
        content: body,
      },
      toRecipients: [
        {
          emailAddress: {
            toName: toName,
            address: toEmail,
          },
        },
      ],
      from: { emailAddress: { fromName: fromName, address: graphUser.email } },
};

const response = await getGraphClient(token[1].accessToken)
   .api(protectedResources.graphMe.usersEndpoint + `${graphUser.id}/sendMail`)
   .post({ message });

functions.logger.log("Response: " + JSON.stringify(response));
2wnc66cl

2wnc66cl1#

若要代表使用Microsoft Graph的用户发送电子邮件,应用程序需要获得必要的委派权限。这些权限包括:

  1. Mail.Send -允许应用以登录用户的身份发送邮件
  2. Mail.ReadWrite -允许应用读取、创建和修改登录用户邮箱中的电子邮件
  3. User.Read -允许应用程序读取登录用户的基本配置文件,包括他们的电子邮件地址
    要添加这些权限,您需要转到Azure门户-〉应用程序注册-〉您的应用程序-〉API权限并添加这些权限。此外,您需要获取具有适当作用域的访问令牌以进行API调用。
lnlaulya

lnlaulya2#

因为送了米亚“米亚。发送”权限就足够了,如文档中所述。
发送邮件:

const options = {
    authProvider,
};

const client = Client.init(options);

const sendMail = {
  message: {
    subject: 'Meet for lunch?',
    body: {
      contentType: 'Text',
      content: 'The new cafeteria is open.'
    },
    toRecipients: [
      {
        emailAddress: {
          address: 'frannis@contoso.onmicrosoft.com'
        }
      }
    ],
    ccRecipients: [
      {
        emailAddress: {
          address: 'danas@contoso.onmicrosoft.com'
        }
      }
    ]
  },
  saveToSentItems: 'false'
};

await client.api('/me/sendMail')
    .post(sendMail);

检查您的访问令牌here并查看是否存在必要的权限。
有关更多信息,请参阅: www.example.com

相关问题