有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用用户凭据通过Microsoft Graph API上的控制台应用程序发送电子邮件

我修改了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 portal中定义,并且应足以在未经管理员同意的情况下使用。 enter image description here

我使用以下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);
        }
    }
}

基本上我需要控制台守护程序的应用程序发送电子邮件代表我没有任何用户交互。凭据将存储在应用程序外部。我不需要权限来代表任意用户发送电子邮件


共 (1) 个答案

  1. # 1 楼答案

    通常,只有当它没有向图形发送令牌或向图形发送有效令牌时,才会出现错误消息。为了进行调试,我首先获取令牌并通过将其粘贴到jwt中进行解码。ms或其他内容,以查看所需的作用域是否如预期的那样位于令牌中。 我还想知道是否不请求用户。读取范围导致邮件出现问题。发送

    另外,你说不需要得到管理员的同意,但在你的情况下是这样的。因为如果管理员不同意,那么用户必须同意。但是,由于您这样做是无头的,因此用户没有机会同意。意味着没有人同意此应用程序以您的身份发送邮件