Сообщение об ошибке
oidc: issuer URL provided to client ("https://accounts.example.com") did not match the issuer URL returned by provider ("https://accounts.example.com/")
Также выводится как
- oidc: issuer did not match the issuer returned by provider, expected "https://accounts.example.com" got "https://accounts.example.com/"
Два URL в кавычках — заданный вами издатель и `issuer` провайдера. go-oidc v3.0–v3.16 выводила «oidc: issuer did not match the issuer returned by provider, expected \"…\" got \"…\"»; нынешняя формулировка и тип `IssuerMismatchError` появились в v3.17.0.
coreos/go-oidc (Go) — *oidc.IssuerMismatchError from oidc.NewProvider
Что это означает
`oidc.NewProvider` загрузил документ обнаружения по переданному вами URL издателя, но поле `issuer` в документе не совпадает с этим URL в точности. OpenID Connect Discovery требует, чтобы они были идентичны, и go-oidc следит за этим, потому что именно со значением `issuer` будет сравниваться `iss` каждого ID-токена. Первый URL в кавычках — ваш, второй — провайдера.
Почему это происходит
Разница в косой черте в конце
частоИздатели Auth0 заканчиваются на `/`, большинство других — нет. Для сравнения `https://tenant.auth0.com` и `https://tenant.auth0.com/` — разные строки.
Отсутствующий или другой сегмент пути
частоKeycloak: `…/realms/<realm>`, Entra ID: `…/<tenant>/v2.0`, Okta: `…/oauth2/default`. Если указать хост без пути или эндпоинт v1 в Entra ID, вернётся документ с другим издателем.
Документ обнаружения загружается через внутренний адрес
иногдаВнутри кластера к провайдеру обращаются по `http://keycloak:8080/...`, а в `issuer` он объявляет свой публичный URL. Расхождение настоящее: в токенах будет публичное значение.
Как исправить
- 1.
Укажите точную строку издателя
Скопируйте `issuer` из документа обнаружения дословно, включая схему, путь и косую черту в конце.
bash curl -s https://accounts.example.com/.well-known/openid-configuration | jq -r .issuer # use exactly this string in oidc.NewProvider(ctx, issuer) - 2.
Разделяйте URL документа обнаружения и издателя только осознанно
`oidc.InsecureIssuerURLContext` позволяет загружать документ обнаружения с одного URL, а токены проверять по публичному издателю. Используйте это только в конфигурациях split-horizon, которые вы контролируете; название функции напоминает о компромиссе.
go // Only when discovery must be fetched from an internal address (for example inside Kubernetes) // while tokens carry the public issuer. The verifier still checks iss against the public value. ctx = oidc.InsecureIssuerURLContext(ctx, "https://login.example.com/realms/main") provider, err := oidc.NewProvider(ctx, "http://keycloak.auth.svc.cluster.local:8080/realms/main")