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

Implement password based authentication #176

Open
deontologician opened this issue Mar 4, 2016 · 27 comments
Open

Implement password based authentication #176

deontologician opened this issue Mar 4, 2016 · 27 comments

Comments

@deontologician
Copy link
Contributor

Right now we just have OAuth. This would be nice, but it requires a bit of care to implement because we're taking the full security burden on ourselves.

@deontologician deontologician added this to the Subsequent milestone Mar 4, 2016
@mattsoftware
Copy link

Although I would love to see passwords die, I also am not delusional and realise they will be around for a long time to come. However this proposal should at minimum mention to also include 2-factor as part of the proposal (google generator would be the probably the most used, maybe ubikey, maybe sms gateway, maybe even email)

There are also other ways to authenticate that do not require passwords, GRC's SQRL for example. So maybe this would be better as 'local authentication' rather than password based (althought thats nitpicking now)

I would love to see some kind of token based authentication, i.e. exchanging username/password/two factor with a token (read JWT) signed with a public/private keypair. Although that would required the private key to be distributed between all the auth servers wanting to do the auth. Pushing the private key to the database would be the logical way to go, but that would require some significant thought on how to handle that correctly in the light that you NEVER want that private key to get out. Even better again would be to have a CA which would provide certs based on a CSR that each server could generate on boot... i.e...
a) compute server boots
b) generates private key and CSR
c) sends CSR to a super private internal server which can provide certs
d) super private internal server sends a cert back to the compute server
e) signs any future auth token with the private key.
... however that now of course adds to complexity when authenticating a token on every request...
a) request comes in with a signed token
b) verifies the token has been signed by verifing with the cert (how does the server find these certs?)
c) verifies the the cert has been issued from our super secret CA (not so hard as that can be easily known across all compute servers)

Not sure how feasible all this is, just trying to think of the most secure way to provide this functionality without compromise.

@deontologician
Copy link
Contributor Author

Right now we have 3 kinds of authentication: unauthenticated (everyone gets the same jwt), anonymous (you get a jwt, and can save it, but if you lose it there's no way to recover), and OAuth. This would basically be similar to anonymous in that you would just get a token, but if you go to a new browser etc you can put in your password and have the server regenerate your token.

I like the suggestion for 2-factor, we should look into that as well

@deontologician
Copy link
Contributor Author

Also, another reason to add this is that people expect it. As a framework, we have some leeway to "encourage good patterns" but if we completely disallow something, people have the freedom to go elsewhere, or worse, implement a home-grown insecure login method on top

@encryptio
Copy link
Contributor

For reference, the algorithm used in "Google Authenticator" is TOTP, as specified in RFC-6238; it's almost exactly code = hmac(shared_secret, str(floor(time() / time_step))) % 1000000 where shared_secret and time_step are known to both parties (usually sent in a QR code.)

All the "enhanced" two-factor apps I know of (including notably Authy) also support TOTP tokens (and the QR code format); it's a simple, well-supported protocol, and there are plenty of small libraries for it.

@deontologician deontologician modified the milestones: Next Major Release, Medium term plans May 20, 2016
@dweldon
Copy link

dweldon commented May 23, 2016

I have a service running meteor, and I'm investigating horizon. A couple of things to consider:

  1. In meteor, the password is hashed on the client before being transmitted to the server (and bcrypted) - some details are listed here. It's nice to make the claim that password-equivalent data isn't stored in the database.
  2. Integrating with a meta-authentication provider like auth0 could be really useful.

@LawJolla
Copy link

LawJolla commented Jul 27, 2016

My business sells to many older, rural buyers. While everyone in Silicon Valley may have a Twitter account, please consider the large swath of America that lives on the farm and not online. Many of my customers don't subscribe to social media (or GitHub!).

I cannot deploy Horizon without some kind of password authentication. I hope this issue gets escalated.

@dv336699
Copy link

@LawJolla that's a very good point from you and the reason why we're still holding on to use horizon.io. We develop internal backend applications (ERP, CRM, user management, etc) and we can't force the user to have a social account.

Also looking forward to this.

@sjmcdowall
Copy link

For FWIW -- we are in the same position. We offer enterprise s/w that sits behind dozens of firewalls etc. (think SAP, PeopleSoft, etc) and obviously having to use a social OAuth mechanism is a total non-starter. We need both the option to use the end customer's LDAP/AD system and/or self-contained user/pw management (and roles too of course) .

@hrj
Copy link

hrj commented Jul 28, 2016

In response to @mattsoftware :

I would love to see some kind of token based authentication, i.e. exchanging username/password/two factor with a token (read JWT) signed with a public/private keypair. Although that would required the private key to be distributed between all the auth servers wanting to do the auth.

Here's a proposal that doesn't require private key to be shared:

  • During registration, the user's password is used to generate a public & private key pair on the client. This can be done by using the password as a seed for a PRNG.
  • The public key is sent to the server which stores it in DB.
  • The private key is not stored anywhere.
  • During authentication, the server sends some challenge text to the client.
  • The client regenerates the key pair based on the password, encrypts the challenge text using the private key, and sends it back to server.
  • Server verifies the authentication request by decrypting the encrypted challenge text using the public key from its database.

@luisherranz
Copy link

Another vote here.

@thinklinux
Copy link

Here is what the meteor guys have done:

Hackpad
accounts-password package

@niieani
Copy link

niieani commented Aug 9, 2016

An optional 2FA would be great, there are some very good yet small JS libraries for generating the codes. Would would be a lovely alternative to 2FA is support for passwordless login approvals (e.g. mobile push "accept button").

@shantanubhadoria
Copy link

I don't think its a good idea to implement authentication mechanisms as a part of horizon framework itself.

This should be a part of plugins. While its fine to have basic user information and logged-in status specified in the framework, how a person can authenticate should be extendible.

I am working on system where authentication can happen with passwords but also with SMS, RFID and nfc(MiFare) cards etc. Its better to have plugins for managing authentications and authentication states as there are usecases for that. To be honest meteor has a good grip on this, it wouldn't hurt to borrow from there.

@luisherranz
Copy link

If I'm not mistaken we can have password authentication in horizon right now using auth0 (#601 and #733).

It would be great to have it without having to use an external saas, but it's ok. One step at a time :)

By the way, congrats on the 2.0.0 release!

@CharlesMcKeever
Copy link

I also develop internal systems that can't use social accounts. Having this as part of a plugin/package would good.

I am looking to migrate off Meteor, but can't use Horizon without this. So I will have to explore other options, which is unfortunate because I like the simplicity that Horizon offers.

@shantanubhadoria
Copy link

Perhaps it might be simpler just to use something like passport integrated into horizon? MEAN uses passport as well and passport supports over 300 pluggable authentication strategies including username/password and all others like github, facebook etc. that horizon currently supports.
http://passportjs.org/

@deontologician
Copy link
Contributor Author

Yeah this is our current plan. We'll replace our current homespun auth
methods with a passport plugin basically.

On Mon, Aug 29, 2016, 22:03 Shantanu Bhadoria notifications@github.com
wrote:

Perhaps it might be simpler just to use something like passport integrated
into horizon? MEAN uses passport as well and passport supports over 300
pluggable authentication strategies including username/password and all
others like github, facebook etc. that horizon currently supports.
http://passportjs.org/


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#176 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAAFVuRw1Np4AB8xrdRek0pOVaU9rDHhks5qk7mdgaJpZM4HpArb
.

@shantanubhadoria
Copy link

@deontologician Awesome! +1 to that!

@yankeeinlondon
Copy link

Oh that sounds like a good idea but a change in direction. What led to that? And of course, the $10k question, when might that hit the shelves?

@zoshe
Copy link

zoshe commented Sep 27, 2016

May want to consider grant. Much smaller and cleaner
https://github.com/simov/grant

@tailsu
Copy link

tailsu commented Oct 10, 2016

Well, the Horizon client can already use JWT's that have been generated by other means with the Horizon({authType: {token: ...}}) constructor. This means that you can use Passport (or whatever) to authenticate your users, generate the JWT token server-side and pass it to the client app through the login API.

I snatched the code that generates the JWT from the source code of the hz make-token CLI command to make it happen. Perhaps a utility function can be added to @horizon/server that setups a new RethinkDB user and generates the token? Something like horizonServer.getTokenForUser(username[, options]). It would then be used like so (hand-wavy):

import passport from 'passport'
import {Strategy as LocalStrategy} from 'passport-local'

...

const app = express();

let horizon = require('@horizon/server')(app.listen(8181), options);

....

passport.use(new LocalStrategy((username, password, done) => {
    if (validateLogin(username, password)) {
        horizon.getTokenForUser(username)
            .then(token => done(null, {token})).catch(done);
    } else {
        done(null, false, {
            message: 'Incorrect user name or password.'
        });
    }
}));

app.get('/api/login', (req, res) => {
    if (!req.user) {
        res.status(403);
    }
    res.json(req.user)
});

app.post('/api/login', passport.authenticate('local'),
    (req, res) => res.json(req.user)
);

The end result is that an authenticated client hitting GET /api/login will get the JWT token that can immediately be passed to the Horizon client constructor.

The getTokenForUser function checks if the user with the given id exists in the database, and creates it if not (sort of like allow_anonymous works). Then, it turns the user id into a JWT.

I think that is actually all that's necessary to have 3rd-party authentication in Horizon. You can even throw away the current OAuth authentication and rely on a recipe for connecting an authenticated user with a RethinkDB user.

Thoughts?

@seddonm1
Copy link

@tailsu good idea. Have you actually built this pattern and if so do you have a repo?

@tailsu
Copy link

tailsu commented Nov 14, 2016

@seddonm1, here you go:

https://github.com/tailsu/horizon-custom-login

@seddonm1
Copy link

Thanks @Stefan. You should post it in the #horizon slack channel.

On 14 Nov. 2016 20:50, "Stefan Dragnev" notifications@github.com wrote:

@seddonm1 https://github.com/seddonm1, here you go:

https://github.com/tailsu/horizon-custom-login


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#176 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADTtUF_BjdAAG1yhQ3-nE_0RQd_SQf8zks5q-C7QgaJpZM4HpArb
.

@tailsu
Copy link

tailsu commented Nov 14, 2016

Please post that for me, thanks!

Am 14.11.2016 10:56 schrieb "Mike Seddon" notifications@github.com:

Thanks @Stefan. You should post it in the #horizon slack channel.

On 14 Nov. 2016 20:50, "Stefan Dragnev" notifications@github.com wrote:

@seddonm1 https://github.com/seddonm1, here you go:

https://github.com/tailsu/horizon-custom-login


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#176 (comment)
,
or mute the thread
<https://github.com/notifications/unsubscribe-
auth/ADTtUF_BjdAAG1yhQ3-nE_0RQd_SQf8zks5q-C7QgaJpZM4HpArb>
.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#176 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAskEvE3q-rKQdd-2xWuS1fMVVBRbnjKks5q-DAzgaJpZM4HpArb
.

@changalberto
Copy link

changalberto commented Apr 12, 2017

If Horizon's goal is to take the pain out of the initial scaffolding, this basic password authentication feature has to be built-in. There is no reason why we should be customizing this. Firebase, Loopback, FeathersJS, MeteorJS, ServerlessJS etc... They all offer this as an option. If you guys don't want to have the burden of taking on this basic authentication system, the community would at least very much appreciate a so called "official" recipe for putting this together with PassportJS.

@luke-robertson
Copy link

Any update on this ?

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

No branches or pull requests