0
votes

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://docs.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.

1
I saw a similar question at stackoverflow.com/questions/59726497/… which got a different error message ("The audience claim value is invalid for current resource...") asked by @JeffMcKay. I am not sure how he resolved his issue. - Duy Ngo
How did you request the token? You need to set the scope to your audience, and your audience must be your token recipient. - Carl Zhao
Check your 'aud' to ensure that it is the api you want to call, and the reason for the 401 You may have used the wrong token or you have used a token that does not belong to the api to call the api. - Carl Zhao
@CarlZhao The uploadUrl was generated and returned in the response of the createUploadSession API. The authtoken param in uploadUrl has 'aud' is "outlook.office.com/api" which I assume it's correct. I've put "outlook.office.com/Mail.ReadWrite" into the scopes when getting the access token from "login.microsoftonline.com/common/oauth2/v2.0/token" API as user consent but it didn't help. Is it possible to get an access token for a combination of Graph and Outlook scopes, e.g.: Mail.ReadWrite and outlook.office.com/Mail.ReadWrite, that works for both API? - Duy Ngo

1 Answers

1
votes

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.