Comments (60)
The password grant type is not implemented the way it should be. I know I am a nobody.. but its clearly obvious that it is not. Every use case defined anywhere says for Native Mobile applications, where you DO NOT want the client secret exposed.. should use the PASSWORD grant type. There are umpteenth web articles that say this should be so.
Here is one from last year https://stormpath.com/blog/the-ultimate-guide-to-mobile-api-security/
I am building a ReactNative app that needs to fetch an access_token from the symfony2 server. According to every piece of documentation I can find.. I need to send grant_type=password&client_id=XXX&username=YYY&password=ZZZ
why are you asking for client_secret when it should NOT be exposed ?
from fosoauthserverbundle.
You need to authenticate the client otherwise anybody who has access to api can use only the username/password to log user in and this nullifies the purpose OAtuh was made for.
from fosoauthserverbundle.
@mvrhov http://tools.ietf.org/html/rfc6749#section-4.3
This grant type should be allowed on trusted applications (basically one owned by the API itself.. i.e. mobile app).
See: http://tools.ietf.org/html/rfc6749#section-4.3.2
.. and in english: http://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified (see Password under "Others" section)
Unless I'm blind or missing something, I don't see anything about the client / secret... I may be wrong.. I was just using the password type in a node.js app without passing anything but username and password using (passport.js and oauth2orize) and I was able to authenticate.
from fosoauthserverbundle.
You should encrypt your client id and client secret, and then decrypt them when needed.
from fosoauthserverbundle.
@alanbem So if we have few clients/users (for our app it is the same) we must send 4 fields to each. I don't think it make difference between stilling 2 or 4 parameters.
Yes I agree, for some applications it make sense but if you follow specification and would like to provide flexible tools, please do not be so categorical about this.
from fosoauthserverbundle.
@j Yes I'm using it for my own app. I guess the issue is that someone could theoretically take my binary and fish out my secret. Which is why I thought you shouldn't be using it.
I suppose if I lock down that client id to only accept the "password" grant type it's somewhat protected. How do other people protect against that?
from fosoauthserverbundle.
This module should support public clients, this missing is currently lead some developpers to implements wrong workaround, like publish the client_secret in public code.
from fosoauthserverbundle.
I faced the same issue, struggled for a long time before ending on this thread.
I solved it by overriding the checkSecret method of the Client Entity (or Document) like below:
public function checkSecret($secret) {
if (in_array("password", $this->getAllowedGrantTypes())) {
return true;
}
return parent::checkSecret($secret);
}
This way, there is no need to override any service or "patch" the OAuth2 server.
I believe this is still secure if only corporate apps (mobile apps or JS frontend app) use the password grant type. But I'll be glad to hear about any security issue.
from fosoauthserverbundle.
If you want to skip client authentication while still using this lib and the password
grant, check out my gist to get some ideas but you might want to check out the security considerations from the oauth spec (see below).
From https://tools.ietf.org/html/rfc6749#section-10.
When client authentication is not possible, the authorization server
SHOULD employ other means to validate the client's identity
... and ...
The authorization server SHOULD NOT process repeated authorization
requests automatically (without active resource owner interaction)
without authenticating the client or relying on other measures to
ensure that the repeated request comes from the original client and
not an impersonator.
This one's important when you think about refresh tokens. If an attacker got a hold of an access and refresh token (not unimaginable) and you aren't requiring any client authentication (since anyone can pass an ID) then the client can be impersonated and you've lost.
Also you cannot validate a client's identity by passing just a client id because https://tools.ietf.org/html/rfc6749#section-2.2
The client identifier is not a secret; it is exposed to the resource owner and MUST NOT be used
alone for client authentication.
However, the spec seems to have purposefully been left open on a lot of things and just makes suggestions in a lot of cases but anyone suggesting to not require the client secret has likely not considered that the spec suggests otherwise. There are still ways you could authenticate your apps/clients without shipping the secret in public code (with your own tokens or something). It's just that they're outside of the scope of the spec and this lib IMO. Not sure I still agree with myself :) I don't know how you'd securely communicate with a public client using oauth unless you're issuing the id and secret for each particular app instance which just opens even more questions about client registration. So if there's no known way to secure public clients in oauth, then maybe null secret should just be allowed by this lib?
Anyway, if you don't care about authenticating clients it's still pretty easy. Check out my gist.
from fosoauthserverbundle.
Thinking about it, you may be right.. I can't find it in the spec, but there may have to be a client_id / secret configured for even this use-case..
@jdelaune I'm assuming you're using this method for your own apps as the spec states, but your apps may still need to be a client and have a secret so the rest of the world can't authenticate their users without getting the user's permission to do so.
https://github.com/FriendsOfSymfony/FOSOAuthServerBundle/blob/master/Model/Client.php#L42
So you can configure all your clients to not be allowed the password grant type, and your client (aka mobile client / desktop client) can be allowed for "password" grant type.
from fosoauthserverbundle.
IMO it's needed: http://williamdurand.fr/licpro-security/#slide118
from fosoauthserverbundle.
@willdurand The link is broken.
I'm a newbie at OAuth2, but using the Facebook SDK for Android I don't need add the secret at the code. This makes me assume that there are some grant_type that don't need the client_secret as Aaron Parecki @jdelaune or @j says.
from fosoauthserverbundle.
@BraisGabin http://licpro.williamdurand.fr/security-slides/#slide118
from fosoauthserverbundle.
so, what?
from fosoauthserverbundle.
It behaves as expected IMO.
from fosoauthserverbundle.
I have the same problem and it's must be re-open.
http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-4.3.2 the original documentation said different
from fosoauthserverbundle.
I ran into the same issue, after looking over the documentation, the secret should not be required where it can not be kept secure (web/js, etc).
from fosoauthserverbundle.
This is security measure and we won't change it. Also Resource Owner Password Credentials
grant should be used in the backend to minimize risk of exposure of the secret.
from fosoauthserverbundle.
Has anyone found a workaround for this issue?
from fosoauthserverbundle.
@ryandjurovich For our project we just create service, it's not true code, it's hack, but maybe it's will be useful for you, code example:
https://gist.github.com/Tobur/8313383
from fosoauthserverbundle.
In the end I committed loads of code to this bundle. https://github.com/bshaffer/oauth2-server-bundle
from fosoauthserverbundle.
@jdelaune yeh I found that bundle yesterday, however I prefer the implementation in this bundle.
I'm just using a default Client record that can only accept the password grant type, and it works with the exception of one issue. For some reason, the standard ClientManager findClientByPublicId
method wasn't working for me when the Client ID is an integer (which I believe it should be?). To get around this issue, I just overrode the ClientManager with an extended class, overriding the findClientByPublicId
method with the following code:
public function findClientByPublicId($id)
{
return $this->findClientBy(array(
'id' => $id,
));
}
from fosoauthserverbundle.
Current implementation is wrong. OAuth2 RFC does not enforce client_id nor secret for grant_type: password for non-confidential clients (like js applications, I'm looking at you @emberjs) http://tools.ietf.org/html/rfc6749#section-4.3
Please, reconsider this; at least, please make the current implementation an opt-out feature.
from fosoauthserverbundle.
Not exactly
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.
Documentation assumes that clients can be divided into confidential (authentication is required for them) and public clients.
Unfortunately at this moment we do not support public clients.
from fosoauthserverbundle.
Unfortunately at this moment we do not support public clients.
That's unfortunate indeed, as this makes the bundle unusable for public clients like JS frontend apps (notably using https://github.com/simplabs/ember-simple-auth/), whereas the OAuth2 addresses this use case.
from fosoauthserverbundle.
For those who need to find a quick workaround when using ember-simple-auth, you may redefine the OAuth2 authenticator (grant_type: password
) to make it send both client_id
and client_secret
to the FOS bundle this way:
Ember.SimpleAuth.Authenticators.OAuth2.reopen({
authenticate: function(credentials) {
var _this = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
var data = {
grant_type: 'password',
username: credentials.identification,
password: credentials.password,
client_id: window.OAuth2ClientCredentials.client_id,
client_secret: window.OAuth2ClientCredentials.client_secret
};
_this.makeRequest(data).then(function(response) {
Ember.run(function() {
var expiresAt = _this.absolutizeExpirationTime(response.expires_in);
_this.scheduleAccessTokenRefresh(response.expires_in, expiresAt, response.refresh_token);
resolve(Ember.$.extend(response, { expires_at: expiresAt }));
});
}, function(xhr, status, error) {
Ember.run(function() {
reject(xhr.responseJSON || xhr.responseText);
});
});
});
}
});
The lines that changes from ember-simple-auth.js are the ones using window.OAuth2ClientCredentials.client_id
and window.OAuth2ClientCredentials.client_secret
.
Simply place this js inside your app.js, after the call to Ember.Application.initializer
.
To make this work, you'll have to define the client_id and the client_secret for your ember app this way (somewhere in your javascript, before your Ember app initialization):
window.OAuth2ClientCredentials = {
client_id: '6_2mjsjflikroghfhjfhdjeoudoggg80swccwgwwg8cooccggog8owwg',
client_secret: '19oq0wj9a79cdjssjdjslleofffsdmksdlksfdfdlzqdsùlsdd08880o4'
};
from fosoauthserverbundle.
Erm I wouldn't recommend that. You're meant to keep your secret secret. Not put it in JavaScript file for all to see. Hence why it shouldn't be required.
Sent from my iPhone
On 9 Apr 2014, at 07:56, Net Gusto [email protected] wrote:
For those who need to find a quick workaround when using ember-simple-auth, you may redefine the OAuth2 authenticator (grant_type: password) to make it send both client_id and client_secret to the FOS bundle this way:
Ember.SimpleAuth.Authenticators.OAuth2.reopen({
authenticate: function(credentials) {
var _this = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
var data = {
grant_type: 'password',
username: credentials.identification,
password: credentials.password,
client_id: window.OAuth2ClientCredentials.client_id,
client_secret: window.OAuth2ClientCredentials.client_secret
};
_this.makeRequest(data).then(function(response) {
Ember.run(function() {
var expiresAt = _this.absolutizeExpirationTime(response.expires_in);
_this.scheduleAccessTokenRefresh(response.expires_in, expiresAt, response.refresh_token);
resolve(Ember.$.extend(response, { expires_at: expiresAt }));
});
}, function(xhr, status, error) {
Ember.run(function() {
reject(xhr.responseJSON || xhr.responseText);
});
});
});
}
});
The lines that changes from ember-simple-auth.js are the ones using window.OAuth2ClientCredentials.client_id and window.OAuth2ClientCredentials.client_secret.Simply place this js inside your app.js, after the call to Ember.Application.initializer.
To make this work, you'll have to define the client_id and the client_secret for your ember app this way (somewhere in your javascript, before your Ember app initialization):
window.OAuth2ClientCredentials = {
client_id: '6_2mjsjflikroghfhjfhdjeoudoggg80swccwgwwg8cooccggog8owwg',
client_secret: '19oq0wj9a79cdjssjdjslleofffsdmksdlksfdfdlzqdsùlsdd08880o4'
};
—
Reply to this email directly or view it on GitHub.
from fosoauthserverbundle.
@jdelaune exactly; this is why this issue should be fixed
from fosoauthserverbundle.
Agree, this should be fixed for correctly implementation
from fosoauthserverbundle.
At least as an optional feature
from fosoauthserverbundle.
The easiest way to add support for this in the library is to allow a null secret in the database (=public client). Client::checkSecret will return true :
public function checkSecret($secret)
{
return (null === $this->secret || $secret === $this->secret);
}
so do OAuthStorage::checkClientCredentials and then OAuth2::grantAccessToken.
from fosoauthserverbundle.
The difference between a public client and a confidential client (a password client in this case) is not just a question of null credentials.
For example a public client must set the "client_id" parameter in each token request, must register redirection uri and so on.
At the moment, these conditions are not verified and your solution looks like pretty and easy to implement but will introduce some lacks and new (security) issues.
IMO, the support of other client types (public client or unregistered client for example) must be introduced in a major update of this library and not just a minor one.
from fosoauthserverbundle.
I'm facing the same issue when trying to set up OAuth2 login for a mobile app. As I don't want to release the client secret and allow client_credential
grant type, I've thought of this alternative : creating a specific Client
for the app which doesn't allow client_credential
grant type, and overriding checkSecret()
this way to avoid having to pass any secret altogether:
public function checkSecret($secret)
{
if (in_array('client_credentials', $this->allowedGrantTypes))
return (null === $this->secret || $secret === $this->secret);
return true;
}
I'm pretty new to OAuth so I don't know if that's a acceptable/safe way to circumvent this issue.
from fosoauthserverbundle.
I solved it by overriding the checkSecret method of the Client Entity (or Document) like below:
public function checkSecret($secret) { if (in_array("password", $this->getAllowedGrantTypes())) { return true; } return parent::checkSecret($secret); }
This way, there is no need to override any service or "patch" the OAuth2 server.
With your patch, every client allowed to use the resource owner password credentials becomes an unsecured client. An attacker can get access token, even using the client credential grant type if it is allowed to the client without any authentication of the client.
As @alanbem and I explained, the library oauth2-php does not support public clients (see #266).
A public client is not a password client with a null secret.
from fosoauthserverbundle.
I am new with OAuth2.0 and I would like to know if @jdelaune suggestion is valid:
"I suppose if I lock down that client id to only accept the "password" grant type it's somewhat protected"
Is it a valid workaround? I would like to use this bundle for my app
from fosoauthserverbundle.
I agree. The "native use case" is the exact reason "password grant" exists.
from fosoauthserverbundle.
also, you can see that the specification REQUIRE not asking for secret in password grant type, see:
http://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified#password
cc: @willdurand
from fosoauthserverbundle.
If any of you need an immediate workaround:
- "Patch" the OAuth class by extending to not verify the secret if the grant type is password:
if (($this->storage->checkClientCredentials($client, $clientCredentials[1]) === false) && ($input["grant_type"]!=self::GRANT_TYPE_USER_CREDENTIALS)) {
Or just copy my pathced file from my gist: https://gist.github.com/AlmogBaku/3164020daee67ec800dd
- Change the server service class:
parameters:
fos_oauth_server.server.class: Rimoto\ApiBundle\Security\RimotoOAuth2
This patch should be done in the oauth-server project, and is secured of course (unlike the suggested solution above which open a huge security hole in your project)
from fosoauthserverbundle.
As @alanbem and I said few weeks/months ago, this library only supports confidential clients (password).
The resource owner password credentials grant type will only work this such client.
If your client is a public one, you cannot use this grant type unless you use a proxy for example.
Every fixes proposed at the moment create security issues we will not accept (secret = null or disabling credential check).
We know this library must be updated to support any kind of clients. A project is under development in my repositories. This project already supports public clients.
from fosoauthserverbundle.
@Spomky can you please elaborate about the differences between "public client" and "confidential client"? from what I understood from googling its only a term for who is the client.. How is that different from the server perspective?
About other bundle- this bundle(or only its server) looks pretty good, and it's supports JWT(which reduce dramatically the server overhead):
https://github.com/bshaffer/oauth2-server-bundle
from fosoauthserverbundle.
I already explained the main differences between public and confidential client on this page (see this answer or this one).
I cannot compare this library with other ones because I do not use them and it really depends on your needs. If you think bshaffer/oauth2-server-bundle
can help your project to go forward, try it.
The project I was talking about in my previous message supports JWT too (grant type and client authentication) including encrypted JWT, but this project is not yet ready for production (see the latest news here). If you want for this issue (and a lot of other issues) to be closed, then you are kindly invited to test this project send us feedback. I appreciate any kind of support.
from fosoauthserverbundle.
@Spomky your project looking really good!
The only one thing I hated is this "plugin" thing. Why?
The convention is symfony for extending an 3rd party is either override a parameter which contains the service class name, or overriding it the config
from fosoauthserverbundle.
We should talk about this topic directly on the project page. Open an issue if you want.
To explain briefly, the plugins allow you to activate the components you need.
Nothing prevent you from extending the bundle or its component and override services.
from fosoauthserverbundle.
Struggling for 1.5 days already to implement secure OAuth for my javascript\ php api application.
Everywhere is only fuzzy recommendations how to do it. any ready for prod alternatives for this library?
Currently I used solution by @johnpancoast, but Im not sure if its secure enough.
I limited client to password and refresh_token grant types + plus my front application is behind SSL.
anyone can help?
from fosoauthserverbundle.
@desmax, I've always been confused about it too! Some people suggest that mobile apps don't need to pass the secret but the spec seems to say not to do that, and it makes sense why. So I personally don't know if I would do it but I'm just going off of my understanding (or misunderstanding) of the spec. It might be "secure enough" or it could be possible that there's no better way to secure public clients. I'm just not a security expert and cannot say. There are plenty of ways to accomplish this within the lib if it is secure enough. Honestly, i think this is more an issue of the OAuth spec lacking in some areas.
Did you look into the other flows in OAuth?
from fosoauthserverbundle.
@johnpancoast yes, looks like I should go with Implicit Grant, with auth via form and then redirect back to front url with access token. But this obviously brings some additional work and login page should be coded in API repo, apart from main web application.
Plus its not clear - what to do after access_token expires, since I don't have access to refresh token?
Should I pass it via url fragment as well?
from fosoauthserverbundle.
from fosoauthserverbundle.
The main issue I see here is that you are trying to use the OAuth2 Framework protocol to authenticate users. But this is not the purpose of the protocol.
OAuth2 only allows a client to access on user resources i.e. it is a delegation protocol. The client knows nothing about the user and cannot guess if it is logged in or not.
If you want to authenticate users using OAuth2, then you have to use the OpenID Connect extension that issues ID Tokens. OIDC provides an easy way to check if the user is still logged in or not using the ID Token.
Unfortunately, this extension is not supported by the bundle nor the library.
from fosoauthserverbundle.
Then when your access token expires send them back to auth
Thank you. I will use that.
Regarding OpenID: This is getting more and more complicated. I amazed that there is still not bullet proofed solution for such a common setup - php api + js web app.
Im not sure that I want "to authenticate users using OAuth2" - my main problem is that I want to secure my api and I though OAuth is the way to go.
from fosoauthserverbundle.
I amazed that there is still not bullet proofed solution for such a common setup - php api + js web app.
This is my issue #0 and why I created this organization
from fosoauthserverbundle.
@Spomky can that already be used in prod for my use case?
from fosoauthserverbundle.
@Spomky yeah, I forgot to mention authorization vs. authentication. OAuth is definitely about authorization but it includes authentication in parts of the spec (or at least vaguely and then leaves authentication to you) and using oauth in combination with other things, like this lib and fos user can work well to do authentication and authorization for a lot of cases while still sticking to the spec, right? I think the issue is both some misunderstanding of oauth and authorization vs. authentication but also just that people want to be able to transfer the ease of those other cases into mobile apps, which are just public clients and oauth seems to leave those cases mostly up to implementer. Your repos look to fill some gaps for sure though!
from fosoauthserverbundle.
@Spomky even if a new bundle may be the right solution. You forget that a lot of symfony applications / frameworks depend on this FOSOAuthServerBundle. You should at least add a config parameter that needs to be set explicitly to allow no client_secret for grant type password.
from fosoauthserverbundle.
I discovered this bundle as an alternative
https://github.com/lexik/LexikJWTAuthenticationBundle
from fosoauthserverbundle.
The purpose of the bundles are different.
This one helps you to delegate access on resources throughout the OAuth2 framework protocol and the one you mentioned provides an user authentication layer based on Json Web Tokens.
from fosoauthserverbundle.
I'm still asking myself why can't I just ignore the grant_type, client_id and client_secret ?
Because we already have username and password as auth parameters.
Can someone explains this to me please ?
from fosoauthserverbundle.
The key parameter grant_type
is required by the specification. With the Password grant type, its value must be paswword
.
client_id
and client_secret
are for the client authentication. Not mandatory if the client is authenticated through the basic authentication scheme for example.
The username
and password
are used to identify the resource owner and are therefore mandatory.
from fosoauthserverbundle.
@Spomky what is the status about your new library https://github.com/OAuth2-Framework/server-library
Is there any roadmap for the replacement of fosoauthserver ?
from fosoauthserverbundle.
Hi @wadjeroudi,
I propose for everybody that is interested in this library to discuss on the dedicated Gitter room.
There was a discussion about an hypothetical replacement of this bundle, but there is not roadmap for that and, for many reasons, I am not sure this is a good idea.
from fosoauthserverbundle.
Ok thx.
What is your advice if you need an oauth server for a webapp using grant type password ?
Switch to an other bundle ?
from fosoauthserverbundle.
Related Issues (20)
- Question about fos_auth_server.yaml
- Security fix for FriendsOfSymfony/oauth2-php HOT 2
- Time for a new release ? HOT 8
- PHP8 support HOT 2
- How to get OAuthToken instead of UserPasswordToken?
- How to add a custom Authentication Provider
- 2.0 timeline and next tagged release? HOT 1
- Suggested way to handle deactivated users
- With symfony 4.4 I'm getting Argument 1 passed to FOS\OAuthServerBundle\Entity\ClientManager::__construct() must be an instance of Doctrine\Common\Persistence\ObjectManager HOT 1
- OAuthToken with null user is not authenticated anymore since symfony 5.4 HOT 5
- PHP 8 Deprecated on getAlias Method HOT 1
- Symfony 6.0 compatibility HOT 6
- PKCE flow support?
- Errors found when auto_mapping is disabled and I didn't heed the instructions about mappings
- SF4 mongodb not finding odm HOT 2
- Officially deprecate the package HOT 5
- Getting attribute 'fieldName': The attribute 'fieldName' is not all !! owed. HOT 3
- PHP 81 Compatibility HOT 2
- Symfony 6 HOT 1
- OAuthStorage still uses EncoderFactoryInterface
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fosoauthserverbundle.