Is there anyway to set the grant_type for the assertion?
hadees opened this issue · 13 comments
According to the specification it looks like you have to set the grant_type to a URI and I don't see anyway of setting that. From what it looks like the grant_type right now is just assertion
?
grant_type
REQUIRED. The format of the assertion as defined by the
authorization server. The value MUST be an absolute URI.
Yes, you are right! The format for grant_type needs to follow urn:ietf:params:oauth:<value>
.
Look at the example request
This would be the relevant document for implementing the proper URI scheme
Just ran into this problem as well. This will be a bit difficult to fix because of the way Doorkeeper is set up. Take a look in /lib/doorkeeper/request.rb
in the Doorkeeper gem. You'll see this (as of version 1.4.1):
require 'doorkeeper/request/authorization_code'
require 'doorkeeper/request/client_credentials'
require 'doorkeeper/request/code'
require 'doorkeeper/request/password'
require 'doorkeeper/request/refresh_token'
require 'doorkeeper/request/token'
module Doorkeeper
module Request
module_function
def authorization_strategy(strategy)
get_strategy strategy, Doorkeeper.configuration.authorization_response_types
rescue NameError
raise Errors::InvalidAuthorizationStrategy
end
def token_strategy(strategy)
get_strategy strategy, Doorkeeper.configuration.token_grant_types
rescue NameError
raise Errors::InvalidTokenStrategy
end
def get_strategy(strategy, available)
fail Errors::MissingRequestStrategy unless strategy.present?
fail NameError unless available.include?(strategy.to_s)
"Doorkeeper::Request::#{strategy.to_s.camelize}".constantize
end
end
end
Here you can see how Doorkeeper is just taking the grant_type
, checking it against a whitelist, and then camelizing and constantizing it to load the proper strategy.
You'd need to change this code to check for grant types of the form urn:ietf:params:oauth:<value>
and pass them to Doorkeeper:::Request::Assertion
.
I'm looking into patching this, but I'm not sure how we could take over the urn:ietf:params:oauth:grant-type:*
(final paragraph of RFC 7521, section 4.1) namespace without potentially trampling other doorkeeper extensions.
The current "Doorkeeper::Request::#{strategy.to_s.camelize}".constantize
obviously won't work with URN-based grant types or cases where multiple URNs might map to the same strategy (say, urn:ietf:params:oauth:grant-type:assertion:facebook
— what a mouthful), so perhaps Doorkeeper could provide a strategy registration table of sorts? Then we could register against /^urn:ietf:params:oauth:grant-type:assertion:(.*)/
and then capture to find our exact assertion
/cc @tute since this will probably need some help from the Doorkeeper side
/cc @tute since this will probably need some help from the Doorkeeper side
Let me know how in doorkeeper's issue tracker, when you get the hand of it. Thanks for stepping up here!
I just put up a PR on the Doorkeeper side that's a start towards strategy / grant type registration. Take a look and see if it's what you had in mind.
If that PR were to be accepted, this gem would be able to include registration in lib/doorkeeper/grants_assertion.rb
like so:
Doorkeeper::GrantFlow.register(
:assertion,
grant_type_matches: /^urn:ietf:params:oauth:grant-type:assertion:(.*)/,
grant_type_strategy: Doorkeeper::Request::Assertion
)
Are you sure we need to add this? If you add in doorkeeper.rb
configuration file:
grant_flows %w(authorization_code client_credentials assertion)
, won't it just work? That will make the token grant type available, on current doorkeeper.
The problem is that there isn't a single "token" grant type, you're expected to use the URN in the spec and denote provider via that URN. You can reread my previous comment above for a more detailed analysis of the spec
A solution that works today, though perhaps a tad hacky:
# in routes
post "oauth/token", to: 'doorkeeper/tokens#create', grant_type: 'assertion', provider: 'facebook', constraints: lambda {|request|
request.headers["rack.request.form_hash"]["grant_type"] == "urn:ietf:params:oauth:facebook"
}
use_doorkeeper # needs to come after
Essentially, it overrides grant_type param to be assertion and provider to be facebook but only if actual grant_type is urn:ietf:params:oauth:facebook
Well, it's not a problem to introduce some mapper or builder class that will handle the logic of transforming grant type value from the request into Doorkeeper class. Just let me know if we need it or introduce a PR for review into Doorkeeper core
pr is more than welcomed