← All changes
|
src/myyoast-client/infrastructure/http/http-client.php
+25
-3
27.8
→
trunk
View file →
| @@ -133,16 +133,38 @@ | ||
| 133 | 133 | ); |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | 136 | /** |
| 137 | - * Checks if the response indicates a use_dpop_nonce error. | |
| 137 | + * Checks if the response indicates a use_dpop_nonce challenge. | |
| 138 | 138 | * |
| 139 | + * Covers both signalling shapes per RFC 9449 §§5.2 and 8: | |
| 140 | + * - Authorization-server style: response body carries `{"error":"use_dpop_nonce"}`. | |
| 141 | + * - Resource-server style: HTTP 401 with `WWW-Authenticate: DPoP error="use_dpop_nonce"` and a fresh `DPoP-Nonce` header. | |
| 142 | + * | |
| 139 | 143 | * @param HTTP_Response $result The parsed response. |
| 140 | 144 | * |
| 141 | - * @return bool Whether this is a DPoP nonce error. | |
| 145 | + * @return bool Whether this is a DPoP nonce challenge. | |
| 142 | 146 | */ |
| 143 | 147 | private function is_dpop_nonce_error( HTTP_Response $result ): bool { |
| 144 | - return ( $result->get_body_value( 'error' ) === 'use_dpop_nonce' ); | |
| 148 | + if ( $result->get_body_value( 'error' ) === 'use_dpop_nonce' ) { | |
| 149 | + return true; | |
| 150 | + } | |
| 151 | + | |
| 152 | + if ( $result->get_status() !== 401 ) { | |
| 153 | + return false; | |
| 154 | + } | |
| 155 | + | |
| 156 | + $headers = $result->get_headers(); | |
| 157 | + if ( ! isset( $headers['www-authenticate'], $headers['dpop-nonce'] ) ) { | |
| 158 | + return false; | |
| 159 | + } | |
| 160 | + | |
| 161 | + $www_authenticate = $headers['www-authenticate']; | |
| 162 | + if ( \is_array( $www_authenticate ) ) { | |
| 163 | + $www_authenticate = (string) \reset( $www_authenticate ); | |
| 164 | + } | |
| 165 | + | |
| 166 | + return ( \stripos( (string) $www_authenticate, 'use_dpop_nonce' ) !== false ); | |
| 145 | 167 | } |
| 146 | 168 | |
| 147 | 169 | /** |
| 148 | 170 | * Executes a single HTTP request with optional DPoP proof injection. |