microsoft-graph-apioutlook-api

Uploading a large attachment using Microsoft Graph got invalid_token error


I am trying to upload a large (> 4mb) attachment to an existing message in Office 365 using Microsoft Graph Java SDK 2.10. I am following these instructions: https://learn.microsoft.com/en-us/graph/outlook-large-attachments?tabs=java

I have successfully created the upload session, and obtained a uploadUrl value that looks like the example in the documentation. Then I start my PUT to this url using ChunkedUploadProvider.

        // Create an upload session
        UploadSession uploadSession = client.me()
                .messages(messageId).attachments()
                .createUploadSession(attachmentItem)
                .buildRequest()
                .post();

        ChunkedUploadProvider<AttachmentItem> chunkedUploadProvider =
                new ChunkedUploadProvider<AttachmentItem>
                        (uploadSession, client, fileStream, attachmentItem.size, AttachmentItem.class);

        // Config parameter is an array of integers
        // customConfig[0] indicates the max slice size
        // Max slice size must be a multiple of 320 KiB
        int[] customConfig = { 12 * 320 * 1024 }; // still < 4MB as API recommended

        // Do the upload
        try {
            chunkedUploadProvider.upload(callback, customConfig);
        } catch (Exception e) {
            log.error("Upload attachment file name {} for message id {}", fileAttachment.name, messageId, e);
        }

My problem is that I get http 401 (Unauthorized) in response:

{
  "error": {
    "code": "InvalidMsaTicket",
    "message": "ErrorCode: \u0027PP_E_RPS_CERT_NOT_FOUND\u0027. Message: \u0027 Internal error: spRPSTicket-\u003eProcessToken failed. Failed to call CRPSDataCryptImpl::UnpackData: Internal error: Failed to decrypt data. :Failed to get session key. RecipientId\u003d293577. spCache-\u003eGetCacheItem returns error.:Cert Name: (null). SKI: 3bd72187c709b1c40b994f8b496a5b9ebd2f9b0c...\u0027",
    "innerError": {
      "requestId": "7276a164-9c13-41cc-b46a-4a86303017a6",
      "date": "2020-09-17T04:55:15"
    }
  }
}

I noticed that the request to create upload session is:

https://graph.microsoft.com/v1.0/me/messages/AQMkADAwATM3ZmYAZS0xNWU2LTc4N1agAAAA==/attachments

while the uploadUrl is:

https://outlook.office.com/api/v2.0/Users('00037ffe-15e6-787e-0000-00000')/Messages('AQMkADAwATM3ZmYAZS0xNVtUUgAAAA==')/AttachmentSessions('AQMkADAwwAAAA=')?authtoken=eyJhbGciOiJSUzI1NiIsImtpZCI6IktmYUNIUlN6bllHMmNIdDRobk9JQnpndlU5MD0iL

which is a different API (Graph vs Outlook).

I already have mail read.write scope added, and that allows me to create a < 4mb attachment. I tried to put "https://outlook.office.com/Mail.ReadWrite" into the scopes when getting the access token but got the same invalid_token issue. What should I do to resolve the issue?

Any help would be appreciated. Thank you.


Solution

  • My bad. The request should not contain Authorization header:

    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.

    Removed the Authorization header and the request works properly.