0
# Authentication
1
2
Microsoft Graph API authentication using MSAL (Microsoft Authentication Library) with support for OAuth refresh tokens and service principal credentials. Provides secure access to OneDrive resources with proper token management and error handling.
3
4
## Capabilities
5
6
### Authentication Client
7
8
Main client class for handling Microsoft Graph API authentication and providing GraphClient instances.
9
10
```python { .api }
11
class SourceMicrosoftOneDriveClient:
12
def __init__(self, config: SourceMicrosoftOneDriveSpec):
13
"""
14
Initialize the OneDrive authentication client.
15
16
Parameters:
17
- config: SourceMicrosoftOneDriveSpec - Configuration containing authentication credentials
18
"""
19
20
@property
21
def msal_app(self):
22
"""
23
Returns a cached MSAL app instance for authentication.
24
Uses @lru_cache for efficient reuse across operations.
25
26
Returns:
27
ConfidentialClientApplication: MSAL application configured with client credentials
28
"""
29
30
@property
31
def client(self):
32
"""
33
Initializes and returns a GraphClient instance for Microsoft Graph API operations.
34
Creates the client on first access and reuses for subsequent calls.
35
36
Returns:
37
GraphClient: Configured Office365 GraphClient for OneDrive operations
38
39
Raises:
40
- ValueError: If configuration is missing or invalid
41
42
Implementation:
43
Checks if configuration exists, then lazily initializes _client with GraphClient
44
passing the _get_access_token method as the token provider.
45
"""
46
47
def _get_access_token(self):
48
"""
49
Retrieves an access token for OneDrive access using configured authentication method.
50
Handles both OAuth refresh token and service principal authentication flows.
51
52
Returns:
53
Dict: Token response containing access_token and metadata
54
55
Raises:
56
- MsalServiceError: If token acquisition fails
57
"""
58
```
59
60
### MSAL Application Configuration
61
62
The MSAL application is configured based on the authentication method:
63
64
```python { .api }
65
# OAuth/Service Principal Configuration
66
authority = f"https://login.microsoftonline.com/{tenant_id}"
67
client_credential = client_secret
68
scope = ["https://graph.microsoft.com/.default"]
69
```
70
71
## Authentication Flows
72
73
### OAuth Flow (User Delegation)
74
75
For interactive user authentication with refresh token:
76
77
```python
78
# OAuth configuration
79
oauth_config = {
80
"credentials": {
81
"auth_type": "Client",
82
"tenant_id": "12345678-1234-1234-1234-123456789012",
83
"client_id": "87654321-4321-4321-4321-210987654321",
84
"client_secret": "your-client-secret",
85
"refresh_token": "your-refresh-token"
86
}
87
}
88
89
# Client initialization
90
from source_microsoft_onedrive.stream_reader import SourceMicrosoftOneDriveClient
91
from source_microsoft_onedrive.spec import SourceMicrosoftOneDriveSpec
92
93
config = SourceMicrosoftOneDriveSpec(**oauth_config)
94
auth_client = SourceMicrosoftOneDriveClient(config)
95
96
# Get GraphClient for API operations
97
graph_client = auth_client.client
98
```
99
100
### Service Principal Flow (Application-Only)
101
102
For service-to-service authentication without user interaction:
103
104
```python
105
# Service principal configuration
106
service_config = {
107
"credentials": {
108
"auth_type": "Service",
109
"tenant_id": "12345678-1234-1234-1234-123456789012",
110
"user_principal_name": "serviceuser@company.onmicrosoft.com",
111
"client_id": "87654321-4321-4321-4321-210987654321",
112
"client_secret": "your-app-secret"
113
}
114
}
115
116
config = SourceMicrosoftOneDriveSpec(**service_config)
117
auth_client = SourceMicrosoftOneDriveClient(config)
118
119
# Access specific user's OneDrive
120
graph_client = auth_client.client
121
user_drive = graph_client.users.get_by_principal_name(
122
config.credentials.user_principal_name
123
).drive.get().execute_query()
124
```
125
126
## Token Management
127
128
### Access Token Retrieval
129
130
```python
131
# Direct access token retrieval
132
access_token = auth_client._get_access_token()
133
134
# Token structure
135
{
136
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIs...",
137
"token_type": "Bearer",
138
"expires_in": 3600,
139
"scope": "https://graph.microsoft.com/.default"
140
}
141
```
142
143
### Token Refresh (OAuth)
144
145
For OAuth flows, tokens are automatically refreshed using the refresh token:
146
147
```python
148
# Automatic refresh in _get_access_token()
149
if refresh_token:
150
result = self.msal_app.acquire_token_by_refresh_token(refresh_token, scopes=scope)
151
else:
152
result = self.msal_app.acquire_token_for_client(scopes=scope)
153
```
154
155
### Service Principal Authentication
156
157
For service principal flows, client credentials are used directly:
158
159
```python
160
# Service principal token acquisition
161
result = self.msal_app.acquire_token_for_client(scopes=scope)
162
```
163
164
## Usage Examples
165
166
### Basic Authentication Setup
167
168
```python
169
from source_microsoft_onedrive.stream_reader import SourceMicrosoftOneDriveClient
170
from source_microsoft_onedrive.spec import SourceMicrosoftOneDriveSpec
171
172
# OAuth configuration
173
config_data = {
174
"credentials": {
175
"auth_type": "Client",
176
"tenant_id": "your-tenant-id",
177
"client_id": "your-client-id",
178
"client_secret": "your-client-secret",
179
"refresh_token": "your-refresh-token"
180
},
181
"drive_name": "OneDrive",
182
"search_scope": "ALL",
183
"folder_path": "."
184
}
185
186
# Initialize authentication
187
config = SourceMicrosoftOneDriveSpec(**config_data)
188
auth_client = SourceMicrosoftOneDriveClient(config)
189
190
# Get authenticated GraphClient
191
try:
192
graph_client = auth_client.client
193
print("Authentication successful")
194
except Exception as e:
195
print(f"Authentication failed: {e}")
196
```
197
198
### Token Validation
199
200
```python
201
# Validate token and get user info
202
try:
203
token_info = auth_client._get_access_token()
204
205
if "access_token" in token_info:
206
print("Token acquired successfully")
207
208
# Use GraphClient for OneDrive operations
209
drives = graph_client.drives.get().execute_query()
210
print(f"Found {len(drives)} accessible drives")
211
212
except Exception as e:
213
print(f"Token acquisition failed: {e}")
214
```
215
216
### Multi-User Service Authentication
217
218
```python
219
# Service principal with multiple user access
220
service_users = [
221
"user1@company.onmicrosoft.com",
222
"user2@company.onmicrosoft.com"
223
]
224
225
for user_principal in service_users:
226
service_config = {
227
"credentials": {
228
"auth_type": "Service",
229
"tenant_id": "your-tenant-id",
230
"user_principal_name": user_principal,
231
"client_id": "your-app-id",
232
"client_secret": "your-app-secret"
233
}
234
}
235
236
config = SourceMicrosoftOneDriveSpec(**service_config)
237
auth_client = SourceMicrosoftOneDriveClient(config)
238
239
try:
240
graph_client = auth_client.client
241
user_drive = graph_client.users.get_by_principal_name(user_principal).drive.get().execute_query()
242
print(f"Accessed drive for {user_principal}: {user_drive.name}")
243
except Exception as e:
244
print(f"Failed to access drive for {user_principal}: {e}")
245
```
246
247
## Error Handling
248
249
### Authentication Errors
250
251
```python
252
from msal.exceptions import MsalServiceError
253
254
try:
255
token = auth_client._get_access_token()
256
except MsalServiceError as e:
257
error_code = e.error_code
258
error_description = e.error_description
259
print(f"MSAL Error {error_code}: {error_description}")
260
```
261
262
### Common Error Scenarios
263
264
- **Invalid Credentials**: Wrong client_id, client_secret, or tenant_id
265
- **Expired Refresh Token**: OAuth refresh token has expired
266
- **Insufficient Permissions**: Application lacks required Microsoft Graph permissions
267
- **Tenant Access Issues**: Service principal not configured for tenant access
268
- **Network Connectivity**: Unable to reach Microsoft authentication endpoints
269
270
## Security Considerations
271
272
### Credential Protection
273
274
- All authentication credentials are marked as secrets in configuration
275
- Tokens are not logged or exposed in error messages
276
- HTTPS-only communication with Microsoft authentication endpoints
277
278
### Permission Scopes
279
280
The connector uses `https://graph.microsoft.com/.default` scope which provides:
281
- Read access to OneDrive files and folders
282
- Access to drive metadata and sharing information
283
- User profile information for service principal flows
284
285
### Token Lifecycle
286
287
- Access tokens typically expire after 1 hour
288
- Refresh tokens have longer lifetime (varies by tenant configuration)
289
- Service principal tokens are acquired on-demand for each operation
290
- Failed authentication triggers immediate retry with fresh token acquisition
291
292
## Microsoft Graph API Integration
293
294
The authentication client provides a configured GraphClient for:
295
- Drive enumeration and access
296
- File and folder operations
297
- Shared item discovery
298
- User profile access (service principal mode)
299
- Metadata extraction and file streaming