【发布时间】:2020-07-07 12:24:48
【问题描述】:
我已调整 Java console application 让用户使用用户名/密码登录以代表他们调用 Microsoft Graph API,而不是检索基本用户数据来发送电子邮件。
但是,虽然原始示例运行良好(我收到了用户电子邮件,请参阅下面的注释代码),但在发送电子邮件时出现此错误:
Graph service exception Error code: NoPermissionsInAccessToken
Error message: The token contains no permissions, or permissions can not be understood.
对于此操作,需要在 Azure 门户中定义 Mail.Send 范围,并且无需管理员同意即可使用。
我使用这些 Microsoft 依赖项:
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>msal4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>com.microsoft.graph</groupId>
<artifactId>microsoft-graph</artifactId>
<version>1.6.0</version>
</dependency>
这是实际代码:
public class MicrosoftGraphMailer {
private final static String CLIENT_APP_ID = "{real-client-app-id}";
private final static String AUTHORITY = "https://login.microsoftonline.com/{real-tenant-id}/";
public static void main(String[] args) throws Exception {
String user = "{real-user}";
String password = "{real-password}";
String token = getUserPasswordAccessToken(user, password).accessToken();
System.out.println(token);
SimpleAuthProvider authProvider = new SimpleAuthProvider(token);
IGraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider(authProvider).buildClient();
Message message = new Message();
message.subject = "My subject";
ItemBody body = new ItemBody();
body.contentType = BodyType.HTML;
body.content = "<h1>My HTML body</h1>";
message.body = body;
List<Recipient> toRecipientList = new LinkedList<>();
Recipient toRecipient = new Recipient();
EmailAddress emailAddress = new EmailAddress();
emailAddress.address = "{real-recipient}";
toRecipient.emailAddress = emailAddress;
toRecipientList.add(toRecipient);
message.toRecipients = toRecipientList;
graphClient.me()
.sendMail(message, false)
.buildRequest()
.post();
/*
String mail = graphClient.me()
.buildRequest()
.get().mail;
System.out.println(mail);
*/
}
private static IAuthenticationResult getUserPasswordAccessToken(String user, String password) throws Exception {
PublicClientApplication app = PublicClientApplication.builder(CLIENT_APP_ID).authority(AUTHORITY).build();
Set<String> scopes = new HashSet<>(Arrays.asList("Mail.Send"));
UserNamePasswordParameters userNamePasswordParam = UserNamePasswordParameters.builder(
scopes, user, password.toCharArray())
.build();
return app.acquireToken(userNamePasswordParam).get();
}
private static class SimpleAuthProvider implements IAuthenticationProvider {
private String accessToken = null;
public SimpleAuthProvider(String accessToken) {
this.accessToken = accessToken;
}
@Override
public void authenticateRequest(IHttpRequest request) {
request.addHeader("Authorization", "Bearer " + accessToken);
}
}
}
基本上,我需要控制台守护程序应用程序来代表我发送电子邮件,而无需任何用户交互。凭据将存储在应用程序之外。我不需要代表任意用户发送电子邮件的权限。
【问题讨论】:
-
您是否同意 Azure 门户中的租户?是您链接到的示例中的步骤 3.7。
标签: java microsoft-graph-api msal