nulab / scala-oauth2-provider

OAuth 2.0 server-side implementation written in Scala

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Client credentials should be optional for password grant type

ctoomey opened this issue · comments

First, thanks for developing and sharing this library. I'm building an OAuth2-protected REST API w/ Play/Scala and this saves me a ton of work.

The way you've implemented it though requires client credentials to always be used, even for the resource owner password credentials grant type for which they're optional per http://tools.ietf.org/html/rfc6749#section-4.3.2: "If the client type is confidential or the client was issued client credentials (or assigned other authentication requirements), the client MUST authenticate with the authorization server as described in Section 3.2.1."

I've looked at how to modify the code to make client credentials optional for this grant type but unfortunately don't see an obvious, clean way to do that as there are many places where this assumption is manifested (TokenEndpoint::handleRequest, Password::handleRequest, and AuthInfo class where clientId is String instead of Option[String]).

So the most expedient thing I can think of to avoid a lot of rework is changing ClientCredentialFetcher::fetch to return a special ClientCredential object with a special clientId representing "no credentials" . That way my DataHandler can check for that special value in validateClient.

Since I need this fixed soon I'll go ahead and make that change in my fork. Do you have any interest in either pulling that change from me or reworking your code to fix this issue more cleanly?

thx,
Chris

Unfortunately that's not enough, as TokenEndpoint::handleRequest also would need to be overridden because of https://github.com/nulab/scala-oauth2-provider/blob/0.9.1/scala-oauth2-core/src/main/scala/scalaoauth2/provider/TokenEndpoint.scala#L20, so that's effectively replacing TokenEndpoint altogether (it's the only method). As you said, Password::handleRequest has to be replaced, again that's the whole class effectively. Lastly, AuthInfo doesn't work in this scenario since its clientId member is type String instead of Option[String], so when there's no clientId it'd have to be set to null or "" which is bad scala form.

Since you've done such a nice job with this library, it'd be nice to modify it to fix this limitation in a cleaner way. If I get time to rework it in a clean way I'll submit a pull request.

Ah, I have understood your point.
We only now support client credential.

So the most expedient thing I can think of to avoid a lot of rework is changing ClientCredentialFetcher::fetch to return a special ClientCredential object with a special clientId representing "no credentials" . That way my DataHandler can check for that special value in validateClient.

I like the way which seems that impact is less for interface.
Most service would use client_id, so I think that client_id is not Optional is not bad.
But I agree with you that is bad scala form.

If I get time to rework it in a clean way I'll submit a pull request.

Thanks, it helps us.

BTW, I have noticed ClientCredentialFetcher::fetch is called twice on TokenEndpoint and GrantHandler.
I would like to fix the behaviour too.

I've made the changes to support client credentials being optional for the password grant type in what I think is a reasonably clean way. I'll submit a pull request for review.

Thanks for working with me on this. Just a note that since the README.md is updated to include an example of using this new feature, you should also update the dependency versions on that to reflect the 0.10.0 version that has the feature.

Thanks your pointing out. I've changed the README.md.