Run your own OAuth2 server
ory.am
ory.am
This is the problem Portier (https://portier.github.io/) and OIDC aim to solve, ie to be able to auth on any website with an auth instance you run.
I love this idea because it's much easier to secure one thing whose sole purpose is authentication than to secure every thing you want to authenticate on.
Portier looks indeed very nice, maybe I'll set up a tutorial how to get those two working together to get full Authentication (portier) + Authorization (Hydra) with using only open source technology.
It's no different than a regular email/password (with password recovery): if I register with user@stravros.io, then that email server becomes empowered to give access to the Gitlab account to anyone it wants. But that's not Gitlab's problem.
See also OpenID.
As in, what I want has been working for ten years?
I'm obviously not late at all, since websites still won't let me delegate my auth.
That's not going to stop people from using those exact values. How many breaches have we seen due to the lack of sane defaults? Tutorial code (especially when written by the people putting out the software) is a default, and it's likely to result in plenty of people running this exact code in production.
That's why I chose to make it explicit, and thus more likely to be caught in review if done.
Of course, this runs the risk that a user will simply "salt" the sample you provide up to the necessary length, which makes the length of their secret effectively the difference between the minimum length and the sample length.
export SYSTEM_SECRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
echo "SYSTEM_SECRET is $SYSTEM_SECRET" @(48..57 + 65..90 + 97..122) | Get-Random -Count 32 | ForEach-Object -Begin {$secret = ''} -Process {$secret += [char] $PSItem} -End {$env:SYSTEM_SECRET = $secret; Write-Host "SYSTEM_SECRET is $secret"}tr -dc A-Za-z0-9_ < /dev/urandom | head -c 32
?
And yes the "cat" is not necessary.
1) admin accounts are generated on startup with random passwords. These are printed on the console on the first startup only.
2) in a configuration format I use, there is a special keyword for using a random string as a value which is different each time the config is parsed.
I think any secure value should be either generated for you or random on each startup unless specified otherwise. It would greatly improve the security of some projects out there.
If you have any questions, feel free to ask ahead.
In our project we ran a master/slave Postgres setup and hourly backups. I don't fully remember the details, but as far as I know that's as safe as you can get regardless of Docker.
It might seem obvious to use volumes and maybe even cronjob to backup your data but a large amount of the instructions you find on the docker hub don't mention it. In any case, if you blindly copy and paste the instruction, you'll end up with data loss.
> Why would crashes be worse than when Postgres is not run in a Docker container?
because if you use docker wrong, the state of your system will leave inside the container and will be flush if you reboot your machine. If you don't use docker, the state of your system will always remain in your disk until your disk crash.
> In our project we ran a master/slave Postgres setup and hourly backups. I don't fully remember the details, but as far as I know that's as safe as you can get regardless of Docker.
It's working great for me too but the point is if you do it wrong, you'll burn yourself. I guess that's the same thing for any piece of tech but behind it's apparent simplicity, it's quite easy to do a mistake with docker and if you do so, say goodbye to your data
Nope, the state of the container will survive until you remove the container. Reboots DO NOT refresh a container (you can have the docker daemon automatically bring your containers back up on reboot).
There is an issue about this (from 2014), but it has yet to be resolved: https://github.com/docker-library/postgres/issues/37
We definitely did not use the container that's in the locker library though. Ours did some custom checks on startup.
I've also seen discussion on an official OAuth2 server plugin, what with the rapid increase of https sites, thanks to the likes of LetsEncrypt.
There's a well supported OAuth2.0 server plugin here: https://en-gb.wordpress.org/plugins/oauth2-provider/
But you'd be wise to only run it via https.
In fact, they managed to remove a lot of oauth1 madness (all the complex signing stuff) by simply requiring TLS and let that layer deal with it.
Conversely, if your organization has a SAML-compatible IdP you get to work with a vast sea of compatible software without really having to think about the integration. Exchange metadata URLs, maybe some URL templates, and you're done.
I've been playing around with it recently and it seems to be a very capable OIDC/Oauth2 provider indeed.
https://gluu.org/docs/ce/authn-guide/U2F/
Installation instructions:
All I need is an openid server.
You can integrate your own backend LDAP server using the cache refresh feature: https://gluu.org/docs/ce/admin-guide/user-management/#ldap-s...
It is pretty beefy though, built for enterprise use cases.
> Think of Keycloak as bleeding edge with quick releases, unpatched, and limited community support. [1]
Seems fine for research, but using it in production seems risky.
Dex for example has a dev mode doing that for you. The downside of Dex is you cannot use your own backend without forking the project, writing your own login page and creating a custom connector for your existing login system.
See it here: https://github.com/RichardKnop/go-oauth2-server
Available as docker container. You can simply deploy it via docker-compose up.
Yours seem to be better maintained though :)
Also what's your reasoning for relying on 4 (etcd, consul, postgres, nats) external dependencies?
https://github.com/RichardKnop/go-oauth2-server#resource-own...
It's basically a login with username and password.
If you want a fully fledged identity provider on top of OAuth2 (so create / update user account, password reset), I have a sample project which extends on the oauth2 repository and builds a full identity provider on top of it: https://github.com/RichardKnop/example-api
About dependencies: only two are required - etcd/consul and postgres. There is no other requirements.
Originally I developed this project while deploying to a CoreOS cluster so etcd was a native choice for storing app configuration in a distributed key store. Consul support was added later in form of a contribution as an alternative to etcd.
I also want to remove dependency on etcd/consul completely and allow just simple configuration via environment variables to make the projec more portable.
I think removing 3rd party dependencies is always a good idea - it keeps things lean and removes ops overhead.
I have another project which I sometimes use as a boilerplate when working on ideas and I need a simple API for my prototyping. It contains all those things as registration, password reset flow etc:
This is a normal authorization flow people are used to from Facebook/Github/LinkedIn, works the same way. See README for images of how the forms look out of the box, without any customization.
If you want to have in app login system, then for such scenario usual way I have implemented this before is to have a separate frontend layer and it works something like this:
1) Frontend (mobile/web app) displays login form
2) Enter username and password
3) Use resource owner credentials grant to obtain access token via API call
4) Now you can make authenticated API calls with the access token (and use refresh token in the background to renew your access token)
In case of web application frontend (let's say NodeJS app), the app would store client ID and secret server side (so you would proxy all requests from client app to Node proxy because we don't want to keep client ID and secret in public JS).
The database contains a simple table to store usernames and passwords for resource owner credentials grant.
There is no API for registering a new user account though which is what I meant.
You can do that manually buy running SQL statement to insert new username and password, or by using the cli and load it from fixtures.
How you handle registering user accounts, updating user data, resetting passwords, all of that I wanted to leave open to implementation as there are various ways in which this can be done and other people might prefer one over another so I didn't want to prescribe a specific way to do it.
I offer my preferred implementation using JSON HAL in my extending project I mentioned above. If anybody is interested, they can still fork my example-api and customize that.
https://github.com/RichardKnop/go-oauth2-server/blob/master/...
go-oauth2-server loaddata \
oauth/fixtures/scopes.yml \
oauth/fixtures/roles.yml \
oauth/fixtures/test_clients.yml
To insert some test data to database.I'm no security expert, but to my understanding the ROPC grant makes sense for highly privileged applications, i.e. 1st party client applications (e.g. main app website, main native iOS client) as explained by http://oauthlib.readthedocs.io/en/latest/oauth2/grants/passw...
I've been looking around in this space for OAuth and auth out of the box alternatives. I've tried Kong's OAuth2 plugin (https://getkong.org/plugins/oauth2-authentication/) but after trying to integrate it felt like I had to write more code than necessary. Also had to configure a lot of APIs, and felt like it was clunky to manage them that way.
I have also tried to play with http://anvil.io, but the authors are busy with another project (https://solid.mit.edu) so Anvil is taking a back seat. Even the Getting Started currently has known unfixed issues.
I am heavily investigating http://www.keycloak.org/, and so far I am really impressed. However though, to deploy you will need to delve into Wildfly/Java configurations. And of course, minimum 512MB to run any Java app on a node.
Dex is also advertised as a solution but it looks like the documentation could do with more information and improvements. https://github.com/coreos/dex Doesn't seem easy to just take and run.
Thanks to comments here, I might these looking at these next:
1. https://github.com/RichardKnop/go-oauth2-server 2. https://portier.github.io/
OAuth2 is only "insecure" in that it relies on TLS for its security: the same as HTTP, IMAP or SMTP. You should never run OAuth2 over a non-HTTPS (i.e. HTTP) connection. The same is true for any other login system.
This is covered in RFC 6819: https://tools.ietf.org/html/rfc6819
However, all server-side attack scenarios listed there are not possible with Hydra. Some of them also boil down to misusing OAuth2 for authentication, which is why we have OpenID Connect.