eaders' => [ 'Accept' => 'application/json' ], ], ); if ( $result->is_transport_failure() ) { $error_message = (string) $result->get_body_value( 'error_description', '' ); throw new Discovery_Failed_Exception( // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Internal exception message. \sprintf( 'Failed to fetch OIDC discovery document from %s: %s', $url, $error_message ), ); } if ( $result->get_status() !== 200 ) { throw new Discovery_Failed_Exception( // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Internal exception message. \sprintf( 'OIDC discovery returned HTTP %d from %s.', $result->get_status(), $url ), ); } $body = $result->get_body(); if ( ! \is_array( $body ) ) { throw new Discovery_Failed_Exception( 'OIDC discovery returned invalid JSON.' ); } $document = new Discovery_Document( $body ); // OIDC Discovery 1.0 Section 4.1: the issuer in the document must match the expected issuer. $expected_issuer = $this->issuer_config->get_issuer_url(); if ( $document->get_issuer() !== $expected_issuer ) { throw new Discovery_Failed_Exception( // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Internal exception message. \sprintf( 'Issuer mismatch: expected %s, got %s.', $expected_issuer, $document->get_issuer() ), ); } \set_transient( $this->get_cache_key(), $body, self::CACHE_TTL ); $this->cached_document = $document; return $document; } }