-
Notifications
You must be signed in to change notification settings - Fork 1
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
Add OAuth2 authentication (57) #87
Conversation
c3ca1cf
to
216b15e
Compare
Force-push to rebase on main and the package update PR |
This comment has been minimized.
This comment has been minimized.
@bsieber-mozilla it sounds like you have a database that was populated before we added alembic. If you don't care about the contents, run |
I just killed all running docker containers to try; still was having errors, re-cloned, killed all docker containers and I think I'm now in business, albeit noticed this on setup...
Will get back to this after standup |
|
Curl test:
Ephemeral DB on local, so I imagine this is fine and not needed to be scrubbed. Curl 2 test (form body):
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a hiccup with my system, but don't believe it would be universal; it all appears to be running and functioning as expected.
LGTM, thanks for these efforts
@@ -194,6 +194,31 @@ python -m alembic upgrade head | |||
exit | |||
``` | |||
|
|||
--- | |||
## OAuth2 Client Credentials |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this documentation!
* python-multipart: Required for FastAPI to process form data * python-jose[cryptography]: Create JSON Web Tokens (JWTs) for use as OAuth2 access tokens * passlib[argon2]: Create and validate salted hashes of passwords
Add a /token endpoint that implements the OAuth2 client credentials grant process. A caller passes a client_id and a client_secret, either in the form body or a header, and gets an OAuth2 token that expires. The token is implemented as a JSON Web Token, signed by the server (HMAC with SHA-256). When the token expires, the client calls /token again. All API endpoints now require a bearer token. The Swagger API docs include a mechanism for authenticating in the browser. This adds new application settings: * CTMS_SECRET_KEY - A long string used in JWT signing. There is a default for development, and it should be unique for each deployment. * CTMS_TOKEN_EXPIRATION - How long, in seconds, that access tokens are valid. Default is 60 minutes.
This script is used to generate API client credentials. It takes a short name to identify the client and a contact email, and generates a client_secret. It prints out the details of the credentials, which can be sent to the requester. It can also be used to update an existing API client, including updating the email address and disabling the credentials.
216b15e
to
2d65674
Compare
Rebased on current |
Proposed changes
To fix issue #57, add OAuth2 authentication using client credentials.
A new endpoint
/token
implements the OAuth2 client credentials grant process. A caller passes aclient_id
and aclient_secret
, either in the form body or a header, and gets an OAuth2 token that expires. The token is implemented as a JSON Web Token or JWT, signed by the server (HMAC with SHA-256). When the token expires (default of 60 minutes), the client calls/token
again.All API endpoints now require a bearer token. The Swagger API docs already include a mechanism for authenticating in the browser.
There's a new database table
api_client
that stores the details for the API clients, along with an alembic migration. A scriptctms/bin/client_credentials.py
can create these. See below for an example.There are new application settings:
CTMS_SECRET_KEY
- A long string used in JWT signing. There is a default for development, and it should be unique for each deployment.CTMS_TOKEN_EXPIRATION
- How long, in seconds, that access tokens are valid. Default is 60 minutes.CTMS_SERVER_PREFIX
- The prefix of the server URL, defaults to the dev value ofhttp://localhost:8000
. Currently used in the output ofclient_credentials.py
, but it may be handy for CSP or other uses.Types of changes
What types of changes does your code introduce?
Checklist
Further comments
Sorry for the size of this PR. It is hard to do just a part of a security feature.
Here's how to use
client_credentials.py
in a local development environment:This will print something like:
You can then start the webserver (
make start
in a different terminal) and enter the credentials into http://localhost:8000/docs. The "Authorize" button in the Swagger docs is over by the right side:You need to authorize before you can use the API endpoints, as hinted by the lock icons.