|
9 | 9 | import os
|
10 | 10 | import re
|
11 | 11 | import uuid
|
| 12 | +import www_authenticate |
12 | 13 |
|
13 | 14 | from msrest import Deserializer, Serializer
|
14 | 15 | from msrest.exceptions import DeserializationError, SerializationError
|
@@ -285,10 +286,31 @@ def _handle_error(self, request, response):
|
285 | 286 | pass
|
286 | 287 | elif response.content is not None:
|
287 | 288 | error_message = response.content.decode("utf-8") + ' '
|
| 289 | + |
288 | 290 | if response.status_code == 401:
|
289 | 291 | full_message_format = '{error_message}The requested resource requires user authentication: {url}'
|
290 |
| - raise AzureDevOpsAuthenticationError(full_message_format.format(error_message=error_message, |
291 |
| - url=request.url)) |
| 292 | + formatted_message = full_message_format.format(error_message=error_message, url=request.url) |
| 293 | + |
| 294 | + # Check for WWW-Authenticate header and extract claims challenge if present |
| 295 | + claims_challenge = None |
| 296 | + if 'WWW-Authenticate' in response.headers: |
| 297 | + www_auth_header = response.headers['WWW-Authenticate'] |
| 298 | + logger.debug('Received WWW-Authenticate header: %s', www_auth_header) |
| 299 | + |
| 300 | + try: |
| 301 | + # Parse the WWW-Authenticate header |
| 302 | + parsed = www_authenticate.parse(www_auth_header) |
| 303 | + |
| 304 | + # Extract the claims challenge from bearer params if present |
| 305 | + claims_challenge = parsed.get("bearer", {}).get("claims") |
| 306 | + if claims_challenge: |
| 307 | + logger.debug('Claims challenge extracted: %s', claims_challenge) |
| 308 | + except Exception as ex: |
| 309 | + # If parsing fails, log the error but continue without claims |
| 310 | + logger.debug('Failed to parse WWW-Authenticate header: %s', str(ex)) |
| 311 | + |
| 312 | + # Raise authentication error with claims challenge if found |
| 313 | + raise AzureDevOpsAuthenticationError(formatted_message, claims_challenge=claims_challenge) |
292 | 314 | else:
|
293 | 315 | full_message_format = '{error_message}Operation returned a {status_code} status code.'
|
294 | 316 | raise AzureDevOpsClientRequestError(full_message_format.format(error_message=error_message,
|
|
0 commit comments