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
Password Grant should not require client_secret #984
Comments
Afaik I've seen this pop up before but we need v8 to be released before we can make changes? @Sephster |
According to https://github.com/thephpleague/oauth2-server/blob/master/CHANGELOG.md#500-rc1---2016-03-24 Support for public clients was added in 5.0.0-RC1 back in 2016. |
So if the client has no secret set then it will work, maybe the change needed is to ask whether or not the client created via artisan is a public or private client? The documentation should mention that client_secret is optional as long as it is not set in the database. |
In the current implementation you can omit the client secret in the request for an access token using a password grant. Instead you must use HTTP Basic Auth to validate with the auth server. I don't think the existing implementation supports public clients but I haven't tested this out fully. |
In Passport, omitting the |
I don't think this is the case but again, I would need time to test this. The current validation works as follows:
In the above, we first try to get a client ID and password using basic auth. We then try to get the client secret that has been passed in as a request parameter, and if this isn't present, we use the basic auth password to authenticate. We then force validation on the client secret (whether this is via basic auth or a request parameter) and if this validation fails e.g. we don't get a valid client, an authentication error is issued. |
Hmm, in Passport I can currently use the flow I described above. I generate a new
Which returns a valid |
Just tested this, and it seems the migrations set the secret column on oauth_clients to not allow null. For this to work, you need to manually add the Passport migrations, and set the column to be nullable. Laravel version: 5.7.28 |
This makes sense, I'm extending Passport and had to copy the migrations in to add other functionally (multi-auth) but what I added would not affect the secret being required or not. |
Passport checks the client secret like so:
If you don't pass a client secret, the default value is null which is cast to a string above. That would become just a blank string. I'm assuming your secret in the database is also a blank string which is why your implementation is working. At the moment though, I don't think the library supports the passing of no secret at all officially. |
You're right, this is exactly what's happening. So you can get around it by having an empty string set as the secret. There doesn't seem to be any validation against whether |
Yeah I think this is a fortunate (for you) quirk of the implementation. I will add an issue to the League's repo to see if we can get this supported officially. I know in the changelogs it says this was done but I don't believe this to be the case. It might have been removed at a later date. Edit: Sorry I realise we already have an issue open for this. Interestingly, this was discussed back in 2015 and the decision was taken to not support public clients using the password grant by default. See this comment here thephpleague/oauth2-server#153 (comment) - It might be the case that we continue with this decision but I would have to look into it further |
@Sephster Thanks for looking into this. While I agree this may require a bigger discussion, perhaps in phpleague first, I do believe this should be allowed. At the end of the day, the developer should know the different grant types and risks each type proposes. In reality, there really is no difference between requiring and not requiring the |
This is very opinionated, but you should probably just not use or allow password grants in the first place, forget without a secret, which would imply you are using it with a public client, being even less secure. For SPA and mobile development the authorization code grant with PKCE is highly recommended and current best practice. This greatly limits the potential attack surface vs a password grant. Please refer to the RFC specifying this for the multitude in reasons behind it. |
@driesvints Got it. Was not aware it blocked PKCE support in Passport but I know of the changes in v8. Doesn't change what the IETF recommendations are though. |
I've released version 8. Cheers for everyone's patience. 👍 |
@Sephster thanks. Now we can add this to Passport as well. If anyone wants to get this into Passport, feel free to send in a PR to the master branch. |
Version 8 requires the client_secret again for password grant so there is nothing that can be done in Passport at the moment. This issue should probably be closed in favor of thephpleague/oauth2-server#889. |
@matt-allan okay, thanks. |
Just in case anyone is still following this issue, this will be possible in the next major version:
|
@matt-allan would that be v8? Any idea if that is going to be this year? Thank you! |
I still haven't found time to work on it, sorry. But I think that within a week or two I'll have some availability. |
V8 is out but i'm still confused on how to work with this |
I don't think that this issue should be closed, as the PKCE is only implemented for the "Authorization Grant" and is still not implemented for the password grant |
@Mina-R-Meshriky PKCE is a technique to mitigate the authorization code being intercepted. Because the password grant does not use an authorization code it isn’t possible to use the PKCE extension. |
@matt-allan you are right my bad the Specification clearly states that the PKCE is for the Authorization Code Grant. |
@matt-allan , please could you give us some clarifications ? |
Yes, as far as I know this should work as indicated by the tests. You need to create a 'public' client, either via the console command ( After doing that you would pass the client_id Passport provides you and you would not pass a client_secret in your rest API call. That being said, I would strongly recommend using the authorization code flow instead if you would like to create a public client. You can skip the authorization prompt if it's a first party client. It's more secure and provides other benefits as explained here. I wrote a guide and an example app showing how to use the auth code flow with a public client here. |
thephpleague/oauth2-server#889
According to this discussion, thephpleague/oauth2-server no longer requires
client_secret
to be passed for password grants but Passport does require it. Can we make this optional as it is in thephpleague/oauth2-server?The text was updated successfully, but these errors were encountered: