目前我正在 Razorpages 中开发电子邮件功能。
我在订单详细信息页面上创建了一个按钮,我想向用户发送一封电子邮件。 我的所有用户都在 Azure AD 中。
这是我的经纪人:
public async Task<IActionResult> OnPostSubmitEmail(string emailTo, CancellationToken cancellationToken)
{
await _exchangeOnlineClient.SendDeniedMail("Subject", User.GetEmail(), emailTo, cancellationToken);
return new JsonResult(new { successMessage = "Email verstuurd" });
}
我的SendDeniedMail方法:
public async Task SendDeniedMail(string subject, string mailFrom, string mailTo, CancellationToken cancellationToken)
{
string content = "content";
var authProvider = new CustomTokenCredentialAuthProvider(_exchangeOnlineConfiguration.TenantId, _exchangeOnlineConfiguration.ClientId, _exchangeOnlineConfiguration.ClientSecret);
var graphClient = new GraphServiceClient(authProvider);
var sendMailPostRequestBody = new SendMailPostRequestBody()
{
Message = new Message()
{
Subject = subject,
Body = new ItemBody()
{
Content = content,
ContentType = BodyType.Text
},
ToRecipients = new List<Recipient>()
{
new Recipient()
{
EmailAddress = new EmailAddress()
{
Address = mailTo
}
}
}
},
SaveToSentItems = false
};
await graphClient.Users[mailFrom].SendMail.PostAsync(sendMailPostRequestBody);
}
我编写了一个自定义令牌提供程序(删除了tenantId和其他敏感内容):
public class CustomTokenCredentialAuthProvider : IAuthenticationProvider
{
private ClientSecretCredential _clientSecretCredential;
private IConfidentialClientApplication _confidentialClientApplicationBuilder;
public CustomTokenCredentialAuthProvider(string tenantId, string clientId, string clientSecret)
{
_clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
var uriBuilder = new UriBuilder("https://login.microsoftonline.com")
{
Path = "tenantId"
};
_confidentialClientApplicationBuilder = ConfidentialClientApplicationBuilder.Create(tenantId).WithClientId(clientId).WithClientSecret(clientSecret).WithAuthority(uriBuilder.Uri).Build();
}
public async Task AuthenticateRequestAsync(RequestInformation request, Dictionary<string, object>? additionalAuthenticationContext = null, CancellationToken cancellationToken = default)
{
var result = await _confidentialClientApplicationBuilder.AcquireTokenForClient(new[] { "https://graph.microsoft.com/.default" }).ExecuteAsync();
request.Headers.Add("Authorization", $"Bearer {result.AccessToken}");
}
}
结果用token填充。
但是当我使用这个令牌时: Microsoft.Graph.Models.ODataErrors.ODataError:访问被拒绝。检查凭据并重试。
那么...我如何正确实现此委托权限流程?
额外信息: 用户通过 Duende 身份服务器 6 登录。这是一个独立的应用程序,与我在此门户中使用的 Azure AD 连接。
我的系统管理员不允许我使用应用程序权限。
我还尝试将范围更改为 api://{ID}/.default 或 api://{ID}/Mail.Send.Deleated 但这会导致:
{"error":"invalid_scope","error_description":"AADSTS1002012:为范围 api://{ID}/Mail.Send.Deleated 提供的值无效。客户端凭据流必须具有带 / 的范围值。默认后缀
但据我了解,这是错误的身份验证流程。
这是您正在使用的发送电子邮件 API,正如我们所看到的,它需要
Mail.Send
API 权限(委托或应用程序),以便 Graph API 可以代表当前登录用户发送电子邮件(委托,/me /sendMail)或代表应用程序(/users/userId/sendMail)。
在您共享的屏幕截图中,您添加了委派 API 权限,但将范围设置为
https://graph.microsoft.com/.default
,用于应用程序 API 权限。我不确定您想使用哪种类型的身份验证。如果您要求用户先登录,然后代表该用户发送电子邮件,则需要将范围更改为 Mail.Send
并使用其他 AuthProvider。这还需要将 Azure AD 身份验证集成到您的应用程序中,以便用户可以使用其 ms 帐户登录。如果您不想要求用户登录,或者您只想拥有管理员帐户才能发送电子邮件,那么您可以使用应用程序 API 权限。然后您需要添加Mail.Send
的应用程序类型。但这需要管理员同意。