You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中调用SharePoint REST API列表项?Graph令牌致401错误求解

解决Android中用Graph令牌调用SharePoint传统REST API的401问题

你的问题核心在于Graph API的访问令牌和SharePoint传统REST API的令牌受众不匹配,直接复用Graph的令牌自然会返回401未授权。下面是具体的解决步骤和代码调整方案:

1. 为什么会出现401?

Graph API的访问令牌受众(aud声明)是https://graph.microsoft.com,而SharePoint的/_api/web/...这类传统REST API要求令牌的受众是你的SharePoint站点根域(比如https://mysharepoint.sharepoint.com)或者具体站点URL。两者的令牌不能通用,必须针对SharePoint资源单独请求令牌。

2. 用MSAL请求SharePoint专属令牌

你需要修改MSAL的令牌请求逻辑,指定SharePoint的资源范围,而非Graph的范围:

  • 针对租户内所有SharePoint站点,范围用https://<你的租户域名>.sharepoint.com/.default
  • 针对特定站点,范围用https://<你的租户域名>.sharepoint.com/sites/MySite/.default

MSAL获取SharePoint令牌的示例代码

// 替换为你的SharePoint资源域名
String SHAREPOINT_SCOPE = "https://mysharepoint.sharepoint.com/.default";

PublicClientApplication pca = PublicClientApplication.create(getContext(), YOUR_CLIENT_ID);
List<String> scopes = Collections.singletonList(SHAREPOINT_SCOPE);

pca.acquireToken(getActivity(), scopes, new AuthenticationCallback() {
    @Override
    public void onSuccess(IAuthenticationResult authResult) {
        // 拿到针对SharePoint的有效令牌
        String sharePointToken = authResult.getAccessToken();
        // 触发SharePoint API调用
        callSharePointRestApi(sharePointToken);
    }

    @Override
    public void onError(MsalException exception) {
        Log.e(TAG, "获取SharePoint令牌失败: " + exception.getMessage());
    }

    @Override
    public void onCancel() {
        Log.d(TAG, "用户取消令牌请求");
    }
});

3. 调整Volley请求的细节

除了替换令牌,还要注意你的SharePoint API URL有个小问题:getbytitle ('Announcements')里的空格会导致URL解析错误,需要改成getbytitle('Announcements')。

调整后的Volley请求代码

// 修正后的SharePoint REST API URL
String SHAREPOINT_API_URL = "https://mysharepoint.sharepoint.com/sites/MySite/_api/web/lists/getbytitle('Announcements')/Items";

JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, SHAREPOINT_API_URL, null,
        new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                Log.d(TAG, "SharePoint API响应: " + response.toString());
                // 这里处理返回数据并更新UI
            }
        },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d(TAG, "SharePoint API请求错误: " + error.toString());
            }
        }) {
    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = new HashMap<>();
        // 使用SharePoint专属令牌
        headers.put("Authorization", "Bearer " + sharePointToken);
        // 添加请求头确保返回简洁的JSON格式
        headers.put("Accept", "application/json;odata=nometadata");
        return headers;
    }
};

// 设置重试策略并加入请求队列
request.setRetryPolicy(new DefaultRetryPolicy(
        3000,
        DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
        DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(request);

4. 额外注意事项

  • 权限配置:在Azure AD应用注册中,必须添加SharePoint相关权限(比如Sites.Read.All、Sites.ReadWrite.All),且需要管理员完成权限同意(租户级应用场景)。
  • 令牌刷新:SharePoint令牌和Graph令牌一样有有效期,MSAL会自动处理令牌刷新,后续可以调用acquireTokenSilent获取刷新后的令牌。

内容的提问来源于stack exchange,提问作者007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:31:34