SharePoint及OneDrive调研
1、认证(获取token)
使用微软的msal4j提供api进行token获取,需要四个参数,如下:
参数说明:
参数 | 说明 |
---|---|
CLIENT_ID | 需要认证的客户端ID信息的值 |
AUTHORITY | 认证的url为“https://login.microsoftonline.com/{tenant_id}” {tenant_id}为对应的租户ID |
SCOPE | 作用域,即当前客户端可以做的操作。默认为:https://graph.microsoft.com/.default |
CLIENT_CREDENTIAL | 客户端密钥,需要用户在microsoft应用注册的页面上给对应的应用添加一个相关的密钥。misrosoft会自动生成一个密钥 |
2、调用对应的API接口获取文件信息以及文件下载的步骤
(1)官网文档链接:在microsoft中提供了对应的API接口说明,其对应接口说明的官网链接为:
https://learn.microsoft.com/en-us/graph/api/overview?view=graph-rest-1.0&preserve-view=true
(2)相关API说明:
首先获取当前账号权限下所有可见用户站点,具体的url为:
https://graph.microsoft.com/v1.0/sites
请求头中需要两个参数:
Authorization:1中获取到的token信息
Content-Type:application/json
(3)获取每一个站点下的文档库列表
https://graph.microsoft.com/v1.0/sites/${id}/drives
参数:
${id}为(2)中返回的每一个用户的id值
请求头中需要两个参数:
Authorization:1中获取到的token信息
Content-Type:application/json
(4)获取每一个文档库中的文档列表
https://graph.microsoft.com/v1.0/drives/${id}/root/children
参数${id}为(3)中返回的每一个文档库的id值
请求头中需要两个参数:
Authorization:1中获取到的token信息
Content-Type:application/json
(5)下载单个文件
https://graph.microsoft.com/v1.0/drives/id/items/{id}/items/id/items/{fileId}/content
参数:
${id}为(3)中返回的文档库的id,主要用于定位当前下载的文件位于那个文档库中
${fileId}为(4)中返回的文件id
请求头中需要两个参数:
Authorization:1中获取到的token信息
Content-Type:application/json
(6)如果当前文档是一个目录文件的话,获取子目录下的所有文档信息
https://graph.microsoft.com/v1.0/drives/${id}/root:/{dir_name}:/children
参数:
${id}为(3)中返回的文档库的id,主要用于定位当前下载的文件位于那个文档库中
{dir_name}为需要获取内层目录所有文档信息
请求头中需要两个参数:
Authorization:1中获取到的token信息
Content-Type:application/json
3、有关driver的说明
表示一个用户的onedrive或者sharepoint中的一个文档库
属性:
driveType:描述资源的类型onedrive个人版返回的是personal;Onedrive企业版返回的是business;Sharepoint文档库返回的是documentLibrary。
4、示例代码
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>msal4j</artifactId>
<version>1.15.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20210307</version>
</dependency>
package org.example.test.testinterface;
import com.microsoft.aad.msal4j.*;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.util.ObjectUtils;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.*;
import java.util.concurrent.ExecutionException;
public class IntegratedWindowsAuthFlow
{
private static String authority;
private static Set<String> scope;
private static String clientId;
public static List<JSONObject> getAllPages(String url, String token)
throws Exception
{
System.out.println("Access Token: " + token);
List<JSONObject> allItems = new ArrayList<>();
try (CloseableHttpClient httpClient = HttpClients.createDefault())
{
while (url != null)
{
HttpGet request = new HttpGet(url);
request.setHeader("Authorization", "Bearer " + token);
request.setHeader("Content-Type", "application/json");
CloseableHttpResponse response = httpClient.execute(request);
int statusCode = response.getCode();
if (statusCode == 200)
{
String responseBody = EntityUtils.toString(response.getEntity());
JSONObject data = new JSONObject(responseBody);
// 获取 "value" 数组中的每个对象
JSONArray values = data.optJSONArray("value");
if (values != null)
{
for (int i = 0; i < values.length(); i++)
{
allItems.add(values.getJSONObject(i));
}
}
// 获取下一页链接
url = data.optString("@odata.nextLink", null);
}
else
{
System.out.printf("Error: %d, %s%n", statusCode,
EntityUtils.toString(response.getEntity()));
break;
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return allItems;
}
private static IAuthenticationResult getToken()
throws MalformedURLException, InterruptedException, ExecutionException
{
ConfidentialClientApplication cca = ConfidentialClientApplication.builder(clientId,
ClientCredentialFactory.createFromSecret(
"CLIENT_CREDENTIAL")).authority(authority).build();
IAuthenticationResult result = cca.acquireToken(
ClientCredentialParameters.builder(scope).build()).get();
return result;
}
public static void main(String[] args)
throws Exception
{
setUpSampleData();
String token = getToken().accessToken();
String url = "https://graph.microsoft.com/v1.0/sites";
List<JSONObject> allItems = getAllPages(url, token);
allItems.forEach(System.out::println);
for (JSONObject allItem : allItems)
{
System.out.println(allItem);
Object id = allItem.get("id");
// 获取文档库列表
String wordListUrl = "https://graph.microsoft.com/v1.0/sites/" + id + "/drives";
List<JSONObject> drives = getAllPages(wordListUrl, token);
for (JSONObject drive : drives)
{
Object id1 = drive.get("id");
Object name = drive.get("name");
System.out.println(id1 + " -> " + name);
String fileUrl =
"https://graph.microsoft.com/v1.0/drives/" + id1 + "/root/children";
List<JSONObject> files = getAllPages(fileUrl, token);
for (JSONObject file : files)
{
Object fileName = file.get("name");
String fileType = "";
if (file.keySet().contains("folder") && !ObjectUtils.isEmpty(
file.get("folder")))
{
fileType = "Folder";
}
else
{
fileType = "File";
}
Object fileId = file.get("id");
try (CloseableHttpClient httpClient = HttpClients.createDefault())
{
String downloadFileUrl =
"https://graph.microsoft.com/v1.0/drives/" + id1 + "/items/" + fileId
+ "/content";
HttpGet request = new HttpGet(downloadFileUrl);
request.setHeader("Authorization", "Bearer " + token);
request.setHeader("Content-Type", "application/json");
try (CloseableHttpResponse response = httpClient.execute(request))
{
int statusCode = response.getCode();
if (statusCode == 200)
{
// 获取响应的输入流
try (InputStream inputStream = response.getEntity().getContent();
FileOutputStream fileOutputStream = new FileOutputStream(
String.valueOf(file.get("name"))))
{
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1)
{
fileOutputStream.write(buffer, 0, bytesRead);
}
System.out.println("文件已成功下载到本地: " + String.valueOf(
file.get("name")));
}
}
else
{
String responseBody = EntityUtils.toString(response.getEntity());
System.err.printf("Error: %d, %s%n", statusCode, responseBody);
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
private static void setUpSampleData()
throws IOException
{
// Load properties file and set properties used throughout the sample
Properties properties = new Properties();
properties.load(new FileInputStream(
Thread.currentThread().getContextClassLoader().getResource("").getPath()
+ "application.properties"));
authority = properties.getProperty("AUTHORITY");
scope = Collections.singleton(properties.getProperty("SCOPE"));
clientId = properties.getProperty("CLIENT_ID");
}
}