Skip to content
This repository was archived by the owner on Mar 16, 2021. It is now read-only.
This repository was archived by the owner on Mar 16, 2021. It is now read-only.

401 when using ChunkedUploadProvider for large mail attachments #52

@jball-vcra

Description

@jball-vcra

Expected behavior
ChunkedUploadProvider.upload(...) uploads the specified file and attaches it to the message, per https://docs.microsoft.com/en-us/graph/outlook-large-attachments?tabs=java.
Actual behavior
401 : Unauthorized upon request.
com.microsoft.graph.core.ClientException: Error code: InvalidAudienceForResource
Error message: The audience claim value is invalid for current resource. Audience claim is 'https://graph.microsoft.com/', request url is 'https://outlook.office.com/api/v2.0/Users...'.
The issue appears to be the API is including an Authorization header in the request, in contradiction with the documentation.

Do not specify an Authorization request header. The PUT query uses a pre-authenticated URL from the uploadUrl property, that allows access to the https://outlook.office.com domain.

Inspection of the authtoken parameter in the upload session's URL shows the correct audience ( "aud": "https://outlook.office.com/api/"), while the auth bearer token's audience is "https://graph.microsoft.com".
Steps to reproduce the behavior
Using an MS Dev account and pregenerated users; microsoft-graph-1.9.0.jar, microsoft-graph-core.1.0.1.jar, microsoft-graph-auth-1.9.0.jar; Java 8.
public class LargeAttachmentUploadError implements GraphExampleConstants {

public static void main(String[] args) throws IOException {
    String recipient = args[0];
    String filepath = args[1];
    Path p = Paths.get(new File(filepath).toURI());
    
    UsernamePasswordProvider authProvider = new UsernamePasswordProvider(
                    clientID,
                    Arrays.asList("https://graph.microsoft.com/.default"),
                    username,
                    password,
                    NationalCloud.Global,
                    tenant,
                    clientSecret);

    IGraphServiceClient graphClient = GraphServiceClient
                    .builder()
                    .authenticationProvider(authProvider)
                    .buildClient();

    graphClient.getLogger().setLoggingLevel(LoggerLevel.DEBUG);   
    
    Message message = new Message();
    message.subject = "Meet for lunch?";
    ItemBody body = new ItemBody();
    body.contentType = BodyType.TEXT;
    body.content = "The new cafeteria is open.";
    message.body = body;
    LinkedList<Recipient> toRecipientsList = new LinkedList<Recipient>();
    Recipient toRecipients = new Recipient();
    EmailAddress emailAddress = new EmailAddress();
    emailAddress.address = recipient; 
    toRecipients.emailAddress = emailAddress;
    toRecipientsList.add(toRecipients);
    message.toRecipients = toRecipientsList;
    message.hasAttachments = true;
    message = graphClient.me().mailFolders("drafts").messages().buildRequest().post(message);
    
    AttachmentItem attachmentItem = new AttachmentItem();
    attachmentItem.name = p.getFileName().toString(); 
    attachmentItem.isInline = false;
    attachmentItem.attachmentType = AttachmentType.FILE; 
    attachmentItem.size = Files.size(p);

    UploadSession uploadSession = graphClient.me().messages(message.id).attachments().createUploadSession(attachmentItem).buildRequest().post();
    try(InputStream inputStream = Files.newInputStream(p)) {
        ChunkedUploadProvider<AttachmentItem> chunkedUploadProvider = new ChunkedUploadProvider<>(uploadSession, graphClient, inputStream, attachmentItem.size, AttachmentItem.class);
        
        IProgressCallback<AttachmentItem> progressCallback = new IProgressCallback<AttachmentItem> () {
            @Override
            // Called after each slice of the file is uploaded
            public void progress(final long current, final long max) {
                System.out.println(String.format("Uploaded %d bytes of %d total bytes", current, max));
            }

            @Override
            public void success(final AttachmentItem result) {
                System.out.println(String.format("Uploaded mail attachment with ID: %s", result.name));
            }

            @Override
            public void failure(ClientException ex) {
                System.out.println("Error uploading mail attachment: " + ex.getMessage());
                throw ex;
            }
        };

        chunkedUploadProvider.upload(progressCallback, new int[] {320 * 1024, 1});
    
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}
AB#5829

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingpromote

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions