How to upload files to sharepoint site's document library using Graph API on android

时间:2018-03-25 20:11:55

标签: android microsoft-graph sharepoint-online

I'm working on an android app (Java Android) that needs to upload excel files to sharepoint site's library, to begin i took this sample using the graph API : https://github.com/microsoftgraph/android-java-connect-sample This sample upload a picture to the user's One Drive repository.

So, Thanks to graph explorer, I changed the query so the picture goes to my site's library and it works, but when i execute the query from my android application i get this error :403 error

My code :

public void uploadPictureToOneDrive(byte[] picture, ICallback<DriveItem> callback) {

    try {
        String id = new String("groupeeiffage.sharepoint.com,1f99a971-b596-4c9b-ba31-784d70c05f49,88ea0abd-a92d-412c-b047-86744a64c0ea");
        mGraphServiceClient
                .getSites(id)
                .getDrive()
                .getRoot()
                .getItemWithPath("me.png")
                .getContent()
                .buildRequest()
                .put(picture, callback);
    } catch (Exception ex) {
        showException(ex, "exception on upload picture to OneDrive ","Upload picture failed", "The upload picture  method failed");
    }
}

I know that's it's an authorization problem but i'm getting lost in the microsoft documentation. How can I allow my app using Graph API to upload files to sharepoint ?

If someone already did something similar i'd really like some help.

1 个答案:

答案 0 :(得分:1)

作为一种解决方法,我们可以使用SharePoint REST API在Android中上传文件。

  1. 从Microsoft身份验证门户获取安全令牌:
  2. public String receiveSecurityToken() throws TransformerException, URISyntaxException {
    
        RequestEntity<String> requestEntity = 
            new RequestEntity<>(buildSecurityTokenRequestEnvelope(), 
            HttpMethod.POST, 
            new URI("https://login.microsoftonline.com/extSTS.srf"));
    
        ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
        DOMResult result = new DOMResult();
    
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.transform(new StringSource(responseEntity.getBody()), result);
    
        Document definitionDocument = (Document) result.getNode();
        String securityToken = xPathExpression.evaluateAsString(definitionDocument);
    
        if (StringUtils.isBlank(securityToken)) { 
            throw new SharePointAuthenticationException("Unable to authenticate: empty token");
        }
    
        return securityToken;
    }
    

    发送到门户网站的信封格式如下:

    <s:Envelope 
        xmlns:s="http://www.w3.org/2003/05/soap-envelope" 
        xmlns:a="http://www.w3.org/2005/08/addressing">
        <s:Header>
            <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>
            <a:ReplyTo>
                <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
            </a:ReplyTo>
            <a:To s:mustUnderstand="1">https://login.microsoftonline.com/extSTS.srf</a:To>
            <o:Security s:mustUnderstand="1" 
                xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                <o:UsernameToken>
                    <o:Username>[username]</o:Username>
                    <o:Password>[password]</o:Password>
                </o:UsernameToken>
            </o:Security>
        </s:Header>
        <s:Body>
            <t:RequestSecurityToken 
                xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
                <wsp:AppliesTo 
                    xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
                    <a:EndpointReference>
                        <a:Address>[SharePoint domain address]</a:Address>
                    </a:EndpointReference>
                </wsp:AppliesTo>
                <t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType>
                <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
                <t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType>
            </t:RequestSecurityToken>
        </s:Body>
    </s:Envelope>
    
    1. 从SharePoint Online服务器获取Cookie:
    2. public List<String> getSignInCookies(String securityToken) throws TransformerException, URISyntaxException {
      
          RequestEntity<String> requestEntity = 
              new RequestEntity<>(securityToken, 
                  HttpMethod.POST, 
                  new URI("[SharePoint domain address]/_forms/default.aspx?wa=wsignin1.0"));
      
          ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
          HttpHeaders headers = responseEntity.getHeaders();
          List<String> cookies = headers.get("Set-Cookie");
      
          if (CollectionUtils.isEmpty(cookies)) {
              throw new SharePointSignInException("Unable to sign in: no cookies returned in response");
          } 
      
          return cookies;
      }
      
      1. 获取对SharePoint Online服务器的请求的签名(FormDigestValue):
      2. public String getFormDigestValue(List<String> cookies) throws IOException, URISyntaxException, 
            TransformerException, JSONException {
        
            MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
            headers.add("Cookie", Joiner.on(';').join(cookies));
            headers.add("Accept", "application/json;odata=verbose");
            headers.add("X-ClientService-ClientTag", "SDK-JAVA");
        
            RequestEntity<String> requestEntity = new RequestEntity<>(headers, 
                HttpMethod.POST, new URI("[SharePoint domain address]/_api/contextinfo"));
        
            ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
            JSONObject json = new JSONObject(responseEntity.getBody());
        
            return json.getJSONObject("d")
                .getJSONObject("GetContextWebInformation").getString("FormDigestValue"); 
        }
        

        最后,我们可以调用REST API来上传文档,如下所示。

        url: http://site url/_api/web/GetFolderByServerRelativeUrl('/Folder Name')/Files/add(url='a.txt',overwrite=true)
        method: POST
        body: "Contents of file"
        Headers: Authorization: "Bearer " + accessToken
                 X-RequestDigest: form digest value
                 content-length:length of post body
        
        public String performHttpRequest(String path, String json, boolean isUpdate) throws Exception {
        
            String securityToken = receiveSecurityToken();
            List<String> cookies = getSignInCookies(securityToken);
            String formDigestValue = getFormDigestValue(cookies);
        
            MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
            headers.add("Cookie", Joiner.on(';').join(cookies));
            headers.add("Content-type", "application/json;odata=verbose");
            headers.add("X-RequestDigest", formDigestValue);                     
        
            RequestEntity<String> requestEntity = new RequestEntity<>(json, 
                headers, HttpMethod.POST, new URI(path));
        
            ResponseEntity<String> responseEntity = 
                restTemplate.exchange(requestEntity, String.class);
        
            return responseEntity.getBody();
        }
        

        更多信息供您参考: