Class: StandardId::Provider::DiscoveryController

Inherits:
ApplicationController show all
Defined in:
app/controllers/standard_id/provider/discovery_controller.rb

Overview

OpenID Connect Discovery (GET /.well-known/openid-configuration).

Why this no longer builds the document by hand

It used to interpolate every endpoint off the issuer with a hardcoded /api segment:

authorization_endpoint: "#{issuer}/api/authorize"

That is the same defect core fixed in standard_id 0.33.0. It is wrong two ways at once: it assumes ApiEngine is mounted at exactly /api, and it conflates the ISSUER with the ENDPOINT BASE. Those are different things — the issuer is a stable security identifier (RFC 8414 §2) that clients match byte-for-byte against their discovery URL and against the iss claim, while the endpoint base is merely where the endpoints happen to live. An app whose issuer does not carry the mount path got a document advertising URLs that 404.

Resolution is now core's: StandardId::Oauth::DiscoveryResolver reads config.oauth.discovery_endpoint_base and config.oauth.discovery_metadata_overrides, and the document itself is built by StandardId::Oauth::DiscoveryDocument, so this document cannot drift from the two core serves.

Setting discovery_endpoint_base is not optional for this engine

Core's own well-known controllers can derive the base from the request, because they are served from INSIDE the ApiEngine mount, where request.script_name IS the mount path. This controller is served from the PROVIDER engine's mount, which is a different mount (typically /). :request would therefore resolve to the origin root and advertise <origin>/oauth/token for an ApiEngine mounted at /api.

So a host serving this document must say where ApiEngine actually is:

c.oauth.discovery_endpoint_base = ->(request:) { "#{request.base_url}/api" }
# or, for a fixed deployment:
c.oauth.discovery_endpoint_base = "https://auth.example.com/api"

That is the hardcoded /api moving out of gem code and into host config, which is the point.

Instance Method Summary collapse

Instance Method Details

#showObject



45
46
47
48
49
50
51
52
53
54
55
# File 'app/controllers/standard_id/provider/discovery_controller.rb', line 45

def show
  resolved = StandardId::Oauth::DiscoveryResolver.resolve(request: request)

  if resolved[:issuer].blank?
    render json: { error: "Issuer not configured" }, status: :not_found
    return
  end

  response.headers["Cache-Control"] = "public, max-age=3600"
  render json: openid_configuration(resolved)
end