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

Implementation of OAuth 2.0 #7251

Closed
jjunineuro opened this issue Mar 7, 2021 · 13 comments
Closed

Implementation of OAuth 2.0 #7251

jjunineuro opened this issue Mar 7, 2021 · 13 comments
Labels
type:feature New feature or improvement of existing feature

Comments

@jjunineuro
Copy link

Hello,

After a rich dialogue about the authentication method of Parse Server (Link Community), I hereby propose the implementation of OAuth 2.0 as the platform's authentication mechanism.

The idea is to increase security and eliminate problems with login expiration time (even if defined, 1 year by default).

The suggestion consists of the following steps:

1 - Add 2 more parameters in ParseOptions:
a) timeoutAccessToken = (int) default: 86400 (1 day)
b) oauthKey = (string) the user must set, suggest the creation of 256 bit key

 The "refreshToken" field must be added to the "_Sessions" class

2 - In the Login and SignUp return methods:
a) remove the "sessionToken" field
b) add the fields: "accessToken", "timeExpiration" and "refreshToken"

3 - The client's APIs, instead of storing the "sessionToken", should store these 3 new fields.

4 - All authentication instead of passing "X-Parse-Session-Token", will pass "Authrozation: Bearer ACESSTOKEN"

5 - If the "accessToken" has expired, the APIs should request the refresh token, example POST "/ parse / users / refresh" passing the parameters:

    {
        "refreshToken": "SECRET REFRESH TOKEN"
    }

the return will be the new "accessToken" for continuity of access, example

  {
       "accessToken": "NEW ACCESS TOKEN",
       "timeExpitation": 0000-00-00 00:00:00
   }

6 - The method to check the current user, when passing the "accessToken" should return the same data that they currently use.

Important: I believe that the APIs did not need to validate the "accessToken" as this must be done on the Parse Server side.

Access token example

Header

{
  "alg": "HS256",
  "typ": "JWT"
}

Payload

{
  "sub": "1234567890", (user's objectId)
  "session": Current session id to identify who is performing the access.
  "iat": 1516239022 (TimeExpiration)
}

Signature Payload

HMACSHA256 (
  base64UrlEncode (header) + "." +
  base64UrlEncode (payload),
  "oauthKey")

Final example of "accessToken"
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

I want to start this contribution to the project, but I would like to hear the suggestions of the community for this idea,

@mtrezza mtrezza added the type:feature New feature or improvement of existing feature label Mar 7, 2021
@mtrezza
Copy link
Member

mtrezza commented Mar 7, 2021

Thanks for suggesting.

Can you please use the template provided when creating an issue?

This is a quite detailed suggestion, there has been some discussion around authentication lately, maybe we can get some feedback from @SebC99, @dblythy, @REPTILEHAUS, @sunshineo, @jdposthuma.

Possibly related to #6849, #6390, #7226.

@jjunineuro
Copy link
Author

Yes @mtrezza, I intend to assemble the model for this suggestion. I will start developing the model. It is very important to listen to the community as new ideas can come up.

@mtrezza
Copy link
Member

mtrezza commented Mar 7, 2021

Adding 2 comments about session renewal security from the forum:

Whether a developer wants [an automated session renewal mechanism] or not depends on the individual security policy, so any such renewal mechanism should be optionally configurable. In addition, these renewal mechanisms usually have a maximum renewal lifespan after which a user has to manually authenticate again, regardless of whether they have a still valid token, to prevent renewing tokens indefinitely. But also a maximum renewal lifespan is something a developer may want or not, so that would also have to be optional or theoretically indefinite, say 999 years.

(...) link the renewal lifespan to the frequency of usage: e.g social network apps, like Facebook or Twitter, that are used every day, so if X days have passed since the last use, the token expires definitely and the user must login again.

@jjunineuro
Copy link
Author

I was following the dialogue on the forum, that is, we should also leave an optional refreshToken deadline and even if you want to use OAuth or the current mechanism, correct?

@jjunineuro
Copy link
Author

Regarding the second comment, linking to the user's usage time, I do not suggest this idea, because the limit stipulated for the renewal of accessToken (OAuth 2.0 protocol) is precisely to force the change of the key to add security in authentication.

@dblythy
Copy link
Member

dblythy commented Mar 8, 2021

This would be a major upgrade with impacts across all SDKs. I'd imagine it would be quite a headache to make this backwards compatible for current deployments. Obviously we don't want server upgrades resulting millions of "invalid session" errors.

What would be the benefit of migrating the requests to "Authorization: Bearer ACESSTOKEN" from "X-Parse-Session-Token"?

Secondly, would the discussed "refresh session token" feature depend on these changes?

Finally:

The idea is to increase security and eliminate problems with login expiration time (even if defined, 1 year by default).

Would you mind elaborating on this statement? It would be good to understand the current limitations, how the change would increase security, what caveats the current system has, etc.

Thanks :)

@jdposthuma
Copy link
Contributor

@jjunineuro - I'm working on implementing Authentication in Parse using an externally validated JWT. It's kind of a "bring-your-own-authentication" approach.

Read about the proposal and the proposed documentation.

I agree that the long-living session token is no longer a best practice and that the short- and long- living token pair is more common these days. For that reason, I prefer it in my designs, although the increased security doesn't mitigate all threats. Especially in the case of XSS, if the access token was compromised, the refresh token would be as well.

Lastly, credit where credit is due - @sunshineo did the original implementation JWT support in parse.

@jjunineuro
Copy link
Author

@dblythy, I'm going to prepare the whole outline of what this methodology will be like. The idea of ​​changing "X-Parse-Session-Token" to cause too many problems I fully agree. You can keep this header by changing only its content, the "accessToken" instead of the "session code". Give me a moment that as soon as I finish the scheme posted here, ok?

@jdposthuma, I didn't start to develop architecture. We are here precisely discussing this, as it is a community dedicated to a project. The idea is not to mitigate or harm the project, but to build and grow as a team. Implementing a technique that is regulated in RFC 6749 and is used by the internet's big players, I don't see it as a step backwards. But rather as an advance. For this purpose, this change will not cause problems for the SDK´s, as it will be a parameter to be chosen, as well as the Authentication by Third Parties. As I understand it, Parse Server aims to be our "Backend", why should I handle the validation of a JWT externally? I don't see this as a solution. I am here to contribute and bring improvements and not harm, again I repeat! The idea is to add this option as an additional option and not change the current login mechanism.

@mtrezza
Copy link
Member

mtrezza commented Mar 8, 2021

Thanks everyone for their engagement in this discussion. Voicing concerns is an important contribution to the discussion to understand the implications of a change. The goal of the discussion is to evaluate all proposed approaches according to value and strategic relevance against their cost of implications for existing deployments.

As such, breaking changes naturally come as an unavoidable cost for continuous development. To mitigate and distribute these costs over time we intend to follow a Phased Depreciation Policy. A breaking change is no categorical stopper for a change, but just costs to weight against the benefits when we ultimately decide for an approach. The discussion sometimes also reveals how to mitigate or even "un-break" a seemingly breaking change.

While opinions will and should differ in a healthy discussion, and each change may impact existing deployments differently, ideally we can come to a common conclusion and pull together on one string at the end.

@SebC99
Copy link
Contributor

SebC99 commented Mar 8, 2021

Could it be a OAuth 2.0 adapter instead of change of the standard auth strategy?
I fully agree there's issues with the actual session implementations, and that a "refresh" token would be a great addition, but I'm not sure about a full replacement.

@SebC99
Copy link
Contributor

SebC99 commented Mar 8, 2021

Even if from a "mobile" point of view as mentioned in the first discussions, it's still possible to save the user's credentials in the device keychain and to use it to "refresh" the token

@dblythy
Copy link
Member

dblythy commented Mar 8, 2021

Could it be a OAuth 2.0 adapter instead of change of the standard auth strategy?

If the implementation of changing the way auth is handled still supports existing session tokens, is opt in, and has improvements over the current method, I don't see why we wouldn't bake it in. I think it can be built in a way that wouldn't affect existing users, but would be beneficial for new users.

It's still possible to save the user's credentials in the device keychain and to use it to "refresh" the token

IMO, from a security perspective (although iOS keychain is solid) it's probably not best if our strategy to handle invalid sessions is to recommend developers store sensitive user information on the device.

@mtrezza
Copy link
Member

mtrezza commented Mar 9, 2021

IMO, from a security perspective (although iOS keychain is solid) it's probably not best if our strategy to handle invalid sessions is to recommend developers store sensitive user information on the device.

I would add that storing the password on the device is really a password anti-pattern. The password should be entered ephemerally and not be stored client side. It should really only be stored on the server, in the user's brain and maybe a password manager. Apple plans to make some WebKit changes in 2022, which will really go against storing local data, unless using a specific API. We can expect other browsers to adapt this (the Chrome team already mentioned it), so secure, persistent storage will much be browser dependent for some years.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:feature New feature or improvement of existing feature
Projects
None yet
Development

No branches or pull requests

5 participants