Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only enable specific grant flows. #295

Merged
merged 5 commits into from
May 3, 2014
Merged

Only enable specific grant flows. #295

merged 5 commits into from
May 3, 2014

Conversation

yorkxin
Copy link
Contributor

@yorkxin yorkxin commented Oct 8, 2013

I'd like to disable some unused grant flows in my API design, such as Resource Owner Password Credentials Grant and Client Credentials Grant. I found there is no way to disable it, so I implemented it.

In practice, the Authorization Endpoint and Token Endpoint would check for available response / grant types (the "strategies") according to the grant flows enabled. For example, if :implicit is not enabled, then Authorization Endpoint will return "Unsupported Response Type" error when response_type is set to token.

By default it enables all the four grant flows. I've also modified initializer file:

  # Change what grant flows are enabled
  # By default it enables all the four grant flows. Remove any of them from
  # the array to disable.
  #
  # grant_flows [
  #               :authorization_code,
  #               :implicit,
  #               :password_credentials,
  #               :client_credentials
  #             ]

Notes:

  1. I don't know whether the commit chitsaou/doorkeeper@110c0d01be8afd8a7713a302333f5c0abb7bad85 is necessary, since the "Unsupported Response Type" is filtered in Doorkeeper::Request. I can remove this commit if you think this is not necessary.
  2. Instead of RSpec tests, I've tested this feature with my demo app, and it seems work.
  3. How do you think about the config values in my commit? In fact I feel that :resource_owner_password_credentials is too long. Update: changed to :password_credentials thanks to advise from @simonbnrd!
  4. Token refreshing on Token Endpoint is currently always-enabled. I think it would make more sense if it is enabled only when use_refresh_token is enabled.
  5. server_spec.rb cannot be run standalone, it would raise some exceptions. I instead tested this spec with rake spec.

Update

According to discussions below, the grant_flows setting is now in array of strings:

grant_flows %w(authorization_code implicit password client_credentials)

@yorkxin
Copy link
Contributor Author

yorkxin commented Oct 17, 2013

@tute Hi, sorry for pinging you here, but I'd like to know how this PR will be? Is it acceptable? Do I need to refactor it? Thanks. :)

@tute
Copy link
Contributor

tute commented Oct 17, 2013

@chitsaou, thank you very much for your work and your poke. I've been on vacations and hanging around Github only for quick comments, your PR deserves more time that I expect to give next week!
Till next, thank you again,
Tute.

@yorkxin
Copy link
Contributor Author

yorkxin commented Oct 17, 2013

@tute oh I see, sorry for the interruption. Enjoy your vacation :)

@kevintom
Copy link

I was thinking of something similar but on the oauth_applications level,

having a list of supported grant_types column on the applications table (default :all ?)

and then doing the check against the applications supported list

not sure if this address the same need
(a little more versatile for me, since i'd like to permit password grant type for my iOS app and android only and have every other api consumer use the authorization_code grant type)

@birarda
Copy link

birarda commented Feb 12, 2014

This would be a very useful feature to have. Is it against the OAuth spec to disable certain grant types for an application?

@yorkxin
Copy link
Contributor Author

yorkxin commented Feb 13, 2014

No, it does not against the spec. Most websites implement only one or two of them. For example, Authorization Code grant type is the only implemented type for most website, and Twitter does only implement Client Credentials grant type.

I've summarized a list of OAuth 2 implementation differences among popular websites on my blog, and you can see that none of them implement all the 4 built-in grant types. Sorry it's in Chinese; here are some brief translations: 自製 = self-made (non-OAuth 2); 半自製 = partially self-made; 無 scope = scope not implemented; spec 相容 = compatible with spec; client 認證 = client authentication

@sjfbo
Copy link
Contributor

sjfbo commented Apr 28, 2014

Really interesting @chitsaou ! / ping @tute 😄

This is also something I was looking for. Now that grant flows such as Resource Owner Password Credentials Grant do not require a client_id and a secret (thanks to OAuth2 spec !), I think that we should be able to disable these grant-types if we want to.

}
end

it "includes ':password' in token_grant_types" do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be :client_credentials instead of :password

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Thank you!

@yorkxin
Copy link
Contributor Author

yorkxin commented Apr 28, 2014

I've left the master branch too far. Maybe I should rebase my changes onto the current version first?

@sjfbo
Copy link
Contributor

sjfbo commented Apr 28, 2014

It may help yes.

@yorkxin
Copy link
Contributor Author

yorkxin commented Apr 29, 2014

OK, I'll rebase onto master later today (living in UTC+8)

@yorkxin
Copy link
Contributor Author

yorkxin commented Apr 29, 2014

I found it is hard to rebase because I don't know how to fix unit tests :(

response_types = []

response_types << :authorization_code if flows.include? :authorization_code
response_types << :password if flows.include? :password_credentials

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [83/80]

@tute
Copy link
Contributor

tute commented Apr 30, 2014

Good work, thank you! Sorry I delayed so much for the review, looking good!

@yorkxin
Copy link
Contributor Author

yorkxin commented Apr 30, 2014

No problem! I'm correcting my code according to your advise. Actually didn't know those symbol DoS issues at that time until recently :( Sorry for that.

@@ -154,7 +171,7 @@

describe "wildcard_redirect_uri" do
it "is disabled by default" do
Doorkeeper.configuration.wildcard_redirect_uri.should be_false
expect(Doorkeeper.configuration.wildcard_redirect_uri).to be_false
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accidentally changed this line. Will revert.

@yorkxin
Copy link
Contributor Author

yorkxin commented Apr 30, 2014

  • All parameters are now in strings instead of symbols.
  • Use a simpler term password for Resource Owner Password Credentials Grant Flow
  • Improved notes about grant_flows command in initializer template.
  • When requesting for token refresh but Doorkeeper's refresh token is not enabled, the server returns unsupported_grant_type error.

I think it's good to merge. Feel free to tell me if there is anything to improve.

@yorkxin yorkxin mentioned this pull request Apr 30, 2014

types << 'refresh_token' if refresh_token_enabled?

types
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • This method's body can be replaced by:
types = flows - ['implicit']
types << 'refresh_token' if refresh_token_enabled?
types
  • We don't need the comment of line 243 (unless we link to the four related parts of the spec, your take).
  • We don't need the flows parameter, as it's an accessible option in this scope.

@tute
Copy link
Contributor

tute commented May 2, 2014

There's something wrong in this PR: https://travis-ci.org/doorkeeper-gem/doorkeeper/jobs/24286507

@yorkxin
Copy link
Contributor Author

yorkxin commented May 2, 2014

Got it. Will dig into this.

@tute
Copy link
Contributor

tute commented May 2, 2014

Probably we do need orm DOORKEEPER_ORM. Sorry, it seems tests need it, I made you take them out.

@tute
Copy link
Contributor

tute commented May 2, 2014

For ActiveRecord they pass because that's default, and when trying mongoid it fails. That will do the trick! Sorry again, my mistake.

@yorkxin
Copy link
Contributor Author

yorkxin commented May 2, 2014

Oh, no problem, and I will not blame on you 😄

I think we need a way to run tests locally using Mongoid.

@tute
Copy link
Contributor

tute commented May 2, 2014

There is, we have to install and run mongoid, and define the ORM env variable. See https://github.com/doorkeeper-gem/doorkeeper/blob/master/.travis.yml.

@yorkxin
Copy link
Contributor Author

yorkxin commented May 2, 2014

Thanks, I'll run test through all mongo adapters and make sure that they pass.

end

scenario 'returns unsupported_grant_type when refresh_token is not in use' do
post token_endpoint_url(:code => @authorization.token, :client => @client, :grant_type => 'refresh_token')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the new Ruby 1.9 hash syntax.
Line is too long. [110/80]

@yorkxin
Copy link
Contributor Author

yorkxin commented May 2, 2014

Fixed. Waiting for Travis CI :p

@tute
Copy link
Contributor

tute commented May 2, 2014

Well, just merged a big Pull Request. Rebase needed, sorry to bother, and thank you for being so responsive!

@yorkxin
Copy link
Contributor Author

yorkxin commented May 2, 2014

No problem. I think I can do another rebase again.

@yorkxin
Copy link
Contributor Author

yorkxin commented May 2, 2014

Some test are failed. I'll fix them and push again.


should_not_have_json 'access_token'
should_have_json 'error', 'unsupported_grant_type'
should_have_json 'error_description', translated_error_message('unsupported_grant_type')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [92/80]

@yorkxin
Copy link
Contributor Author

yorkxin commented May 2, 2014

Done rebasing! I've also converted hash to 1.9 style.

By the way according to test cases, it seems that if specifying grant_flows in symbols (i.e. %i(implicit password)) the grant flow restriction will also work.

@yorkxin
Copy link
Contributor Author

yorkxin commented May 2, 2014

Previously the tests are setting grant_flows in array of symbols. I've corrected them to array of strings, but the tests pass in both cases.

tute added a commit that referenced this pull request May 3, 2014
Only enable specific grant flows.
@tute tute merged commit 0ce32ff into doorkeeper-gem:master May 3, 2014
@tute
Copy link
Contributor

tute commented May 3, 2014

Thank you! ❤️

@yorkxin
Copy link
Contributor Author

yorkxin commented May 3, 2014

👍 Thanks a lot!

@sjfbo
Copy link
Contributor

sjfbo commented May 3, 2014

Good job @chitsaou and @tute !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants