-
Notifications
You must be signed in to change notification settings - Fork 129
Routes
The installation generator will update your config/routes.rb to define all required routes:
Rails.application.routes.draw do
use_doorkeeper_openid_connect
# your routes
endThis will mount the following routes:
GET /oauth/userinfo
POST /oauth/userinfo
GET /oauth/discovery/keys
GET /.well-known/openid-configuration
GET /.well-known/oauth-authorization-server
GET /.well-known/webfinger
With the exception of the hard-coded /.well-known paths (see RFC 5785) you can customize routes in the same way as with Doorkeeper, please refer to this page on their wiki.
discovery_url_options lets you tweak the host, protocol, or port of the published jwks_uri, but not the path itself. To advertise a custom path — while keeping /oauth/discovery/keys working for existing clients during a rollover — mount the discovery controller at the new path and re-point the oauth_discovery_keys_url helper at it via direct:
# config/routes.rb
Rails.application.routes.draw do
use_doorkeeper_openid_connect
# 1. Mount the custom path under a non-conflicting helper name
get "/-/jwks",
to: "doorkeeper/openid_connect/discovery#keys",
as: :custom_jwks
# 2. Re-point oauth_discovery_keys_url at the new path
direct(:oauth_discovery_keys) { |opts| custom_jwks_url(opts) }
endAfter this, .well-known/openid-configuration returns "jwks_uri": "https://example.com/-/jwks", and the original /oauth/discovery/keys route still responds (handy during a rollover).
Note
A naive match "/-/jwks", ..., as: :oauth_discovery_keys won't work — Rails has refused to reuse a route name since 4.0 and raises ArgumentError: Invalid route name, already in use: 'oauth_discovery_keys'. The direct helper sidesteps this by overriding the URL helper itself rather than re-declaring the route name.
If your app authenticates more than one kind of resource owner (e.g. a User
and a Customer Devise model) you may want to mount Doorkeeper — and this engine
— more than once, each under its own namespace:
# config/routes.rb
Rails.application.routes.draw do
scope :users, as: :users do
use_doorkeeper { controllers authorizations: "users/authorizations" }
use_doorkeeper_openid_connect
end
scope :customers, as: :customers do
use_doorkeeper { controllers authorizations: "customers/authorizations" }
use_doorkeeper_openid_connect
end
endMost of the request flow is model-agnostic: the resource_owner_authenticator
block can dispatch on whichever owner is signed in (current_user || current_customer), and claims / userinfo / ID token generation follow from
whatever it returns.
The one piece that needs attention is the discovery document.
DiscoveryController#provider_response
builds the published endpoints by calling named route helpers
(oauth_authorization_url, oauth_token_url, …) directly. The
discovery_url_options setting (added in #126) lets you
override the host / protocol / port of those URLs, but not which named
helper is resolved — so under multiple mounts every namespace's discovery
document would point at the same set of endpoints.
The idiomatic fix is to subclass the discovery controller per namespace and re-point the helper calls at that namespace's routes:
# app/controllers/users/discovery_controller.rb
module Users
class DiscoveryController < Doorkeeper::OpenidConnect::DiscoveryController
private
# Re-point each helper used by `provider_response` at the namespaced route.
def oauth_authorization_url(opts = {})
users_oauth_authorization_url(opts)
end
def oauth_token_url(opts = {})
users_oauth_token_url(opts)
end
def oauth_revoke_url(opts = {})
users_oauth_revoke_url(opts)
end
def oauth_userinfo_url(opts = {})
users_oauth_userinfo_url(opts)
end
def oauth_discovery_keys_url(opts = {})
users_oauth_discovery_keys_url(opts)
end
# ...and `oauth_introspect_url` / `oauth_dynamic_client_registration_url`
# if you advertise those.
end
end# config/routes.rb (inside the `:users` scope)
get "/.well-known/openid-configuration",
to: "users/discovery#provider", as: :users_openid_connect_configRepeat for the customers namespace. Each .well-known/openid-configuration
then advertises the endpoints for its own namespace.
Note
See #192 for the original discussion. First-class multi-mount support is not provided out of the box; the per-namespace controller override above is the supported extension pattern for now.