OneDrive / SharePoint - Acesso programático (Guia técnico)
Resumo
Documento técnico com instruções passo-a-passo para: registrar uma aplicação no Azure AD, obter tenantId, clientId, clientSecret, configurar permissões apropriadas e métodos comuns para consumir conteúdo do SharePoint / OneDrive (incluindo links compartilhados). Contém exemplos em Python (MSAL + requests), exemplos curl, e diagramas mermaid para ilustrar fluxos de autenticação.
Pré-requisitos
- Conta com privilégios de Administrador Global ou Administrador de Aplicações no tenant Azure AD onde a aplicação será registrada.
- Licença Microsoft 365 ativa para o(s) usuários cujo OneDrive/SharePoint serão consumidos (OneDrive for Business / SharePoint Online).
- Python 3.8+ (recomendado). Pacotes usados nos exemplos:
msal,requests,pandas(opcional).
Instalação mínima:
pip install msal requestsVisão geral dos fluxos
1. Registrar a aplicação no Azure AD (passo a passo)
- Acesse portal: Microsoft Entra ID (Azure Active Directory) → App registrations → New registration.
- Defina nome (por exemplo
sharepoint-data-consumer). - Supported account types: escolha conforme necessidade (single-tenant para testes internos).
- Redirect URI: não é obrigatório para client credentials; para delegated flows (ex.: auth code) informe
https://login.microsoftonline.com/common/oauth2/nativeclientou outra URI adequada.
Após criar a aplicação, anote:
- Application (client) ID →
CLIENT_ID - Directory (tenant) ID →
TENANT_ID
2. Configurar credenciais (client secret)
- App registrations → sua app → Certificates & secrets → New client secret.
- Anote o
client_secretgerado (ex.:CLIENT_SECRET). - Recomenda-se usar Azure Key Vault para armazenar segredos em produção.
3. Configurar permissões Microsoft Graph
Decida o tipo de acesso: App-only (daemon/pipeline automático) ou Delegated (com usuário interativo).
Recomendações de permissões para pipelines automáticos (App-only)
Microsoft Graph (Application permissions):
Files.Read.All(ler arquivos em toda a organização)Files.ReadWrite.All(se precisar escrever)Sites.Read.All/Sites.ReadWrite.All(para bibliotecas SharePoint)User.Read.All(opcional — listar usuários)
Após adicionar as permissões, clicar em Grant admin consent para o tenant.
Permissões para cenários delegados (se houver login humano)
Microsoft Graph (Delegated permissions):
Files.Read/Files.ReadWriteSites.Read.All(se necessário)
4. Obter token (exemplos)
4.1 App-only (Client Credentials) — Python (MSAL)
import msal
TENANT_ID = "<TENANT_ID>"
CLIENT_ID = "<CLIENT_ID>"
CLIENT_SECRET = "<CLIENT_SECRET>"
authority = f"https://login.microsoftonline.com/{TENANT_ID}"
SCOPE = ["https://graph.microsoft.com/.default"]
app = msal.ConfidentialClientApplication(
client_id=CLIENT_ID,
authority=authority,
client_credential=CLIENT_SECRET,
)
token_resp = app.acquire_token_for_client(scopes=SCOPE)
if "access_token" not in token_resp:
raise SystemExit(token_resp)
access_token = token_resp["access_token"]
headers = {"Authorization": f"Bearer {access_token}"}Observações:
/.defaultusa as permissões de aplicação concedidas no portal.- Tokens de app-only representam a aplicação, não um usuário.
4.2 Delegated (Device Code) — quando o usuário puder interagir
import msal
CLIENT_ID = "<CLIENT_ID>"
AUTHORITY = "https://login.microsoftonline.com/common" # ou tenants específicos
SCOPES = ["Files.Read.All", "offline_access", "User.Read"]
app = msal.PublicClientApplication(CLIENT_ID, authority=AUTHORITY)
flow = app.initiate_device_flow(scopes=SCOPES)
print(flow["message"]) # usuário abre o browser e autentica
token = app.acquire_token_by_device_flow(flow)
access_token = token["access_token"]
headers = {"Authorization": f"Bearer {access_token}"}5. Endpoints úteis Microsoft Graph
- Listar drives do tenant (app-only):
GET /drives - Acessar drive de usuário (app-only):
GET /users/{userPrincipalName}/driveouGET /drives/{drive-id} - Listar filhos de um driveItem:
GET /drives/{drive-id}/items/{item-id}/childrenouGET /users/{user}/drive/root/children - Baixar conteúdo de arquivo (driveItem):
GET /drive/items/{item-id}/contentou usar@microsoft.graph.downloadUrlretornado pela API. - Acessar item a partir de link de compartilhamento:
GET /shares/{shareId}/driveItemouGET /shares/{shareId}/driveItem/children
6. Consumir um link compartilhado (procedimento técnico)
Share links da UI devem ser codificados para uso no Graph como shareId. A codificação padrão:
- Prepend
u!à URL de compartilhamento original. - Fazer base64-url-safe (substituir
+→-,/→_e remover padding=).
Exemplo (Python):
import base64
def link_to_share_id(shared_link: str) -> str:
raw = "u!" + shared_link
b = base64.urlsafe_b64encode(raw.encode("utf-8")).decode("utf-8")
return b.rstrip("=")
shared_link = "https://tenant.sharepoint.com/:f:/g/personal/rafael/... ?e=XYZ"
share_id = link_to_share_id(shared_link)
# Listar children do share (se for pasta)
url = f"https://graph.microsoft.com/v1.0/shares/{share_id}/driveItem/children"
resp = requests.get(url, headers=headers).json()
# Cada item retornará @microsoft.graph.downloadUrl para download diretoNotas:
- Nem todos os compartilhamentos permitem acesso anônimo via API; em alguns casos a API exigirá autenticação válida.
7. Exemplo completo: listar e baixar arquivos de um link compartilhado (sem credenciais quando permitido)
import base64
import requests
import msal
# Se o share for público e a API aceitar, o fluxo abaixo pode funcionar sem client secret.
# 1) Autenticação app-only (opcional, necessário se o share não for anulamente público)
TENANT_ID = "<TENANT_ID>"
CLIENT_ID = "<CLIENT_ID>"
CLIENT_SECRET = "<CLIENT_SECRET>"
app = msal.ConfidentialClientApplication(
client_id=CLIENT_ID,
authority=f"https://login.microsoftonline.com/{TENANT_ID}",
client_credential=CLIENT_SECRET,
)
token = app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])
headers = {"Authorization": f"Bearer {token['access_token']}"}
# 2) Converter shared link
shared_link = "https://factoritcombr-my.sharepoint.com/:f:/g/personal/rafael/...?e=XYZ"
raw = "u!" + shared_link
share_id = base64.urlsafe_b64encode(raw.encode()).decode().rstrip("=")
# 3) Listar conteúdo
list_url = f"https://graph.microsoft.com/v1.0/shares/{share_id}/driveItem/children"
items = requests.get(list_url, headers=headers).json()
for it in items.get("value", []):
name = it["name"]
download_url = it.get("@microsoft.graph.downloadUrl")
if download_url:
data = requests.get(download_url)
with open(name, "wb") as fh:
fh.write(data.content)8. Curl minimal (token obtido previamente)
# obter metadados de um driveItem
curl -H "Authorization: Bearer $TOKEN" \
"https://graph.microsoft.com/v1.0/drives/{drive-id}/items/{item-id}"
# baixar conteúdo
curl -H "Authorization: Bearer $TOKEN" \
"https://graph.microsoft.com/v1.0/drives/{drive-id}/items/{item-id}/content" -o arquivo.ext9. Boas práticas de segurança e operacionais
- Nunca commitar
client_secretem repositórios. Use Azure Key Vault ou managed identities. - Conceda permissões mínimas necessárias (principle of least privilege).
- Para pipelines automáticas em Azure, prefira Managed Identity + Key Vault quando possível.
- Rotacione secrets periodicamente.
- Registre logs de acesso e monitore usando Azure Monitor/Azure AD sign-in logs.
10. Troubleshooting (erros comuns)
"/me request is only valid with delegated authentication flow": não use/mecom app-only; substitua por/users/{user}oudrives/{drive-id}.User not found: userPrincipalName não existe no tenant ou o ambiente é MSA (conta pessoal) e não Azure AD.invalidAuthenticationTokenao acessar/shares/{shareId}: o link pode não ser acessível via API (visualização no browser não garante API access). Peça ao proprietário para gerar um link de download “Anyone with the link” com permissão de download.
11. Referências
- Microsoft Graph: Permissions reference
- Microsoft Graph: Access shared items (
/sharesendpoint) - Microsoft Graph: DriveItem resource and download (
@microsoft.graph.downloadUrl) - MSAL Python: acquiring tokens (client credentials, device code)
- OneDrive / OneDrive API: shares encoding
12. Anexos — exemplos práticos (snippets reutilizáveis)
OneDriveClient (esqueleto)
class OneDriveClient:
def __init__(self, tenant_id, client_id, client_secret):
import msal
self.app = msal.ConfidentialClientApplication(
client_id=client_id,
authority=f"https://login.microsoftonline.com/{tenant_id}",
client_credential=client_secret,
)
self.token = None
def get_token(self):
if not self.token:
self.token = self.app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])['access_token']
return self.token
def headers(self):
return {"Authorization": f"Bearer {self.get_token()}"}
def download_shared_folder(self, shared_link, target_dir="."):
import os, requests
share_id = link_to_share_id(shared_link)
url = f"https://graph.microsoft.com/v1.0/shares/{share_id}/driveItem/children"
resp = requests.get(url, headers=self.headers()).json()
for it in resp.get('value', []):
dl = it.get('@microsoft.graph.downloadUrl')
if dl:
r = requests.get(dl)
path = os.path.join(target_dir, it['name'])
with open(path, 'wb') as fh:
fh.write(r.content)