首页 > 解决方案 > Microsoft graph - 访问令牌验证失败。无效的观众 - 错误

问题描述

我正在尝试使用 Angular 应用程序中的 Graph API 发送邮件。

在 Azure 活动目录中,我已授予 Mail.Send 和其他邮件相关内容的 API 权限。

下面是代码

const resource = {
    grant_type : 'client_credentials',
    clientID: '****************************',
    redirectUri: 'http://localhost:4200/',
    validateAuthority : true,
    popUp: true,
    scopes: ['mail.send'],
    resource : 'https://graph.microsoft.com'
  };

  let murl : any
  murl = 'https://graph.microsoft.com/v1.0/users/' + 'testuser@abcd.onmicrosoft.com' + '/sendMail';

  this.token = await this.msalService.acquireTokenSilent(resource)
      .catch((reason) => {
        // console.log(reason);
      });

      let header = new HttpHeaders({
        'Content-Type': 'application/json',
          'Authorization': 'Bearer ' + this.token.accessToken});
      let options = { headers: header };

      let resp =  this.http.post(murl, this.sendMailDet, options)
       resp.subscribe(
          (data)=>{
            console.log( data);
        }
        );

但是当我发送邮件时,我得到以下错误。

error: {code: "InvalidAuthenticationToken", message: "Access token validation failure. Invalid audience.",…}
code: "InvalidAuthenticationToken"
innerError: {date: "2021-01-06T04:52:20", request-id: "*********",…}
message: "Access token validation failure. Invalid audience."

我在资源中使用范围:['mail.send'] 仍然收到此错误。我也只使用 this.msalService.acquireTokenSilent(resource) 中的 accessToken。

jwt.ms 中的令牌将 aud 显示为“aud”:“https://graph.microsoft.com”和“scp”:“Directory.Read.All email Mail.Read Mail.Read.Shared Mail.ReadBasic Mail.ReadWrite Mail.ReadWrite.Shared Mail.Send Mail.Send.Shared MailboxSettings.Read MailboxSettings.ReadWrite User.Export.All User.Invite.All User.ManageIdentities.All User.Read User.Read.All User.ReadBasic.All User.ReadWrite User.ReadWrite.All profile openid",

谁能帮我检查一下这个问题。

标签: angularauthenticationmicrosoft-graph-apiaccess-token

解决方案


我必须从 angular 发送令牌,因为首先会显示接受或取消弹出窗口。所以不得不从角度处理。但这给了我问题中提到的错误。所以我为此创建了一个 API,并从 Angular 发送他的令牌和其他详细信息。

这是角部分

data : 带有 From、To、CC、bcc、emailbody 等的对象。使用这些值,我们在 API 中创建 json 电子邮件格式

async sendmail(data): Promise<Boolean>  
  {

    let result : any ; 
    const resource = {
      clientID: environment.config.identityConfig.clientId , 
      redirectUri: environment.config.identityConfig.redirectUri , // 'http://localhost:4200/'
      validateAuthority : true,
      popUp: true,
      scopes: ['mail.send'],
      resource : 'https://graph.microsoft.com'
    };
    this.token = await this.msalService.acquireTokenSilent(resource)
    .catch((reason) => {
      console.log(reason);
    });

    this.atoken = this.token.accessToken;
    data.EMailAccessToken = this.token.accessToken;
    this.mailHttpService.post('/sendmailgapi', data, null, null, ApiUrl.FileService). // This is custom 
   subscribe((data) => {
     result = data; 
   });

   return result;
  }

然后在API中,

this.applicationContext.GetGraphClient() :这是另一个使用客户端 ID、租户 ID、ClientSecret 和使用 ConfidentialClientApplicationBuilder 的方法,我们创建了一个 Graph 客户端。

sendMailDto : 传递对象

GraphServiceClient graphClient = this.applicationContext.GetGraphClient();
var fromEmail = sendMailDto.EMailFrom ; // 
var accessToken = sendMailDto.EMailAccessToken;
var message = createMessage(sendMailDto);
var restClient = new RestClient("https://graph.microsoft.com/v1.0/users/" + fromEmail + "/sendMail");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Bearer " + accessToken 
request.AddParameter("", message, ParameterType.RequestBody);
IRestResponse response = restClient.Execute(request);
               

我不确定这是否是正确的方法,但我不得不做一个解决方法来解决这个问题。


推荐阅读