Mensaje de error
oidc: issuer URL provided to client ("https://accounts.example.com") did not match the issuer URL returned by provider ("https://accounts.example.com/")
También se muestra como
- oidc: issuer did not match the issuer returned by provider, expected "https://accounts.example.com" got "https://accounts.example.com/"
Las dos URL entre comillas son el emisor configurado y el `issuer` del proveedor. go-oidc v3.0–v3.16 imprimía «oidc: issuer did not match the issuer returned by provider, expected \"…\" got \"…\"»; el texto actual y el tipo `IssuerMismatchError` llegaron en v3.17.0.
coreos/go-oidc (Go) — *oidc.IssuerMismatchError from oidc.NewProvider
Qué significa
`oidc.NewProvider` descargó el documento de descubrimiento de la URL del emisor que se le indicó, y el campo `issuer` del documento no es exactamente esa URL. OpenID Connect Discovery exige que ambas sean idénticas, y go-oidc lo hace cumplir porque el `iss` de cada token de ID se comparará con el valor de `issuer`. La primera URL entre comillas es la tuya; la segunda, la del proveedor.
Por qué ocurre
Diferencia en la barra final
frecuenteLos emisores de Auth0 terminan en `/`; la mayoría de los demás, no. Para la comparación, `https://tenant.auth0.com` y `https://tenant.auth0.com/` son cadenas distintas.
Segmento de ruta ausente o distinto
frecuenteKeycloak `…/realms/<realm>`, Entra ID `…/<tenant>/v2.0`, Okta `…/oauth2/default`. Si apuntas al host sin la ruta, o al endpoint v1 de Entra ID, recibes un documento con un emisor distinto.
Descubrimiento descargado a través de una dirección interna
ocasionalDentro de un clúster se llega al proveedor como `http://keycloak:8080/...`, mientras que este anuncia su URL pública como `issuer`. La discrepancia es real: los tokens llevarán el valor público.
Cómo solucionarlo
- 1.
Configurar la cadena exacta del emisor
Copia `issuer` del documento de descubrimiento tal cual, incluidos el esquema, la ruta y la barra final.
bash curl -s https://accounts.example.com/.well-known/openid-configuration | jq -r .issuer # use exactly this string in oidc.NewProvider(ctx, issuer) - 2.
Separar deliberadamente la URL de descubrimiento y el emisor
`oidc.InsecureIssuerURLContext` permite descargar el descubrimiento de una URL y validar los tokens contra el emisor público. Úsalo solo en configuraciones de horizonte dividido que controles; el nombre recuerda el compromiso que supone.
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")