Skip to content

Commit 480af91

Browse files
author
aeneasr
committed
all: basic draft
1 parent 7adad58 commit 480af91

27 files changed

+1329
-2
lines changed

.coveralls.yml

Whitespace-only changes.

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea
2+
*.iml
3+
.cover
4+
*.log

.travis.yml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
sudo: required
2+
3+
services:
4+
- docker
5+
6+
env:
7+
- DOCKER_BIND_LOCALHOST=true
8+
9+
language: go
10+
11+
go:
12+
- 1.5
13+
14+
install:
15+
- go get golang.org/x/tools/cmd/vet
16+
- go get github.com/axw/gocov/gocov
17+
- go get github.com/mattn/goveralls
18+
- go get golang.org/x/tools/cmd/cover
19+
- go get github.com/golang/lint/golint
20+
- go get -t ./...
21+
22+
script:
23+
- go vet -x ./...
24+
- ./coverage --coveralls

CONTRIBUTING.md

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Contribution Guide
2+
3+
We welcome and encourage community contributions to Fosite.
4+
5+
Since the project is still unstable, there are specific priorities for development. Pull requests that do not address these priorities will not be accepted until Fosite is production ready.
6+
7+
Please familiarize yourself with the Contribution Guidelines and Project Roadmap before contributing.
8+
9+
There are many ways to help Fosite besides contributing code:
10+
11+
- Fix bugs or file issues
12+
- Improve the documentation
13+
14+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
15+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
16+
**Table of Contents**
17+
18+
- [Contributing Code](#contributing-code)
19+
- [Code Style](#code-style)
20+
- [Developer’s Certificate of Origin](#developer%E2%80%99s-certificate-of-origin)
21+
- [Pull request procedure](#pull-request-procedure)
22+
- [Conduct](#conduct)
23+
24+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
25+
26+
## Contributing Code
27+
28+
Unless you are fixing a known bug, we **strongly** recommend discussing it with the core team via a GitHub issue before getting started to ensure your work is consistent with Fosite's roadmap and architecture.
29+
30+
All contributions are made via pull request. Note that **all patches from all contributors get reviewed**. After a pull request is made other contributors will offer feedback, and if the patch passes review a maintainer will accept it with a comment. When pull requests fail testing, authors are expected to update their pull requests to address the failures until the tests pass and the pull request merges successfully.
31+
32+
At least one review from a maintainer is required for all patches (even patches from maintainers).
33+
34+
Reviewers should leave a "LGTM" comment once they are satisfied with the patch. If the patch was submitted by a maintainer with write access, the pull request should be merged by the submitter after review.
35+
36+
## Code Style
37+
38+
Please follow these guidelines when formatting source code:
39+
40+
* Go code should match the output of `gofmt -s`
41+
42+
## Developer’s Certificate of Origin
43+
44+
All contributions must include acceptance of the DCO:
45+
46+
```text
47+
Developer Certificate of Origin
48+
Version 1.1
49+
50+
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
51+
660 York Street, Suite 102,
52+
San Francisco, CA 94110 USA
53+
54+
Everyone is permitted to copy and distribute verbatim copies of this
55+
license document, but changing it is not allowed.
56+
57+
58+
Developer's Certificate of Origin 1.1
59+
60+
By making a contribution to this project, I certify that:
61+
62+
(a) The contribution was created in whole or in part by me and I
63+
have the right to submit it under the open source license
64+
indicated in the file; or
65+
66+
(b) The contribution is based upon previous work that, to the best
67+
of my knowledge, is covered under an appropriate open source
68+
license and I have the right under that license to submit that
69+
work with modifications, whether created in whole or in part
70+
by me, under the same open source license (unless I am
71+
permitted to submit under a different license), as indicated
72+
in the file; or
73+
74+
(c) The contribution was provided directly to me by some other
75+
person who certified (a), (b) or (c) and I have not modified
76+
it.
77+
78+
(d) I understand and agree that this project and the contribution
79+
are public and that a record of the contribution (including all
80+
personal information I submit with it, including my sign-off) is
81+
maintained indefinitely and may be redistributed consistent with
82+
this project or the open source license(s) involved.
83+
```
84+
85+
To accept the DCO, simply add this line to each commit message with your name and email address (`git commit -s` will do this for you):
86+
87+
```text
88+
Signed-off-by: Jane Example <[email protected]>
89+
```
90+
91+
For legal reasons, no anonymous or pseudonymous contributions are accepted ([contact us](mailto:[email protected]) if this is an issue).
92+
93+
## Pull request procedure
94+
95+
To make a pull request, you will need a GitHub account; if you are unclear on this process, see GitHub's documentation on [forking](https://help.github.com/articles/fork-a-repo) and [pull requests](https://help.github.com/articles/using-pull-requests). Pull requests should be targeted at the `master` branch. Before creating a pull request, go through this checklist:
96+
97+
1. Create a feature branch off of `master` so that changes do not get mixed up.
98+
1. [Rebase](http://git-scm.com/book/en/Git-Branching-Rebasing) your local changes against the `master` branch.
99+
1. Run the full project test suite with the `go test ./...` (or equivalent) command and confirm that it passes.
100+
1. Run `gofmt -s` (if the project is written in Go).
101+
1. Accept the Developer's Certificate of Origin on all commits (see above).
102+
1. Ensure that each commit has a subsystem prefix (ex: `controller: `).
103+
104+
Pull requests will be treated as "review requests," and maintainers will give feedback on the style and substance of the patch.
105+
106+
Normally, all pull requests must include tests that test your change. Occasionally, a change will be very difficult to test for. In those cases, please include a note in your commit message explaining why.
107+
108+
## Conduct
109+
110+
Whether you are a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back.
111+
112+
* We are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, disability, ethnicity, religion, or similar personal characteristic.
113+
* Please avoid using nicknames that might detract from a friendly, safe and welcoming environment for all.
114+
* Be kind and courteous. There is no need to be mean or rude.
115+
* We will exclude you from interaction if you insult, demean or harass anyone. In particular, we do not tolerate behavior that excludes people in socially marginalized groups.
116+
* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or a member of the Fosite core team immediately.
117+
* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behaviour is not welcome.
118+
119+
We welcome discussion about creating a welcoming, safe, and productive environment for the community. If you have any questions, feedback, or concerns please let us know with a GitHub issue.

MAINTAINERS

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Aeneas Rekkas <[email protected]> (github: arekkas)
2+
Thomas Aidan Curran <[email protected]> (github: tacurran)

README.md

+176-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,176 @@
1-
# oauth2
2-
A simple and extensible oauth2 server framework
1+
# ![Fosite](fosite.png)
2+
3+
Simple and extensible OAuth2 server-side helpers with enterprise security and zero suck.
4+
This library implements [rfc6749](https://tools.ietf.org/html/rfc6749) and enforces countermeasures suggested in [rfc6819](https://tools.ietf.org/html/rfc6819).
5+
6+
[![Build Status](https://travis-ci.org/ory-am/fosite.svg?branch=master)](https://travis-ci.org/ory-am/fosite?branch=master)
7+
[![Coverage Status](https://coveralls.io/repos/ory-am/fosite/badge.svg?branch=master&service=github)](https://coveralls.io/github/ory-am/fosite?branch=master)
8+
9+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
10+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
11+
**Table of Contents**
12+
13+
- [Motivation](#motivation)
14+
- [Good to know](#good-to-know)
15+
- [Security](#security)
16+
- [Encourage security by enforcing it!](#encourage-security-by-enforcing-it)
17+
- [Secure Tokens](#secure-tokens)
18+
- [No state, no token](#no-state-no-token)
19+
- [Opaque tokens](#opaque-tokens)
20+
- [Advanced Token Validation](#advanced-token-validation)
21+
- [Encrypt credentials at rest](#encrypt-credentials-at-rest)
22+
- [Implement peer reviewed IETF Standards](#implement-peer-reviewed-ietf-standards)
23+
- [Provide extensibility and interoperability](#provide-extensibility-and-interoperability)
24+
- [Tokens](#tokens)
25+
- [Usage](#usage)
26+
- [Store](#store)
27+
- [Authorize Endpoint](#authorize-endpoint)
28+
- [OpenID Connect](#openid-connect)
29+
- [Token Endpoint](#token-endpoint)
30+
31+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
32+
33+
## Motivation
34+
35+
Why write another OAuth2 server side library for Go Lang?
36+
37+
Other libraries are perfect for a non-critical set ups, but [fail](https://github.com/RangelReale/osin/issues/107) to comply with enterprise security standards.
38+
This is unfortunately not an issue exclusive to Go's eco system but to many other eco systems as well.
39+
40+
OpenID Connect on top of OAuth2? Not possible with popular OAuth2 libraries. Current libraries do not support capture
41+
the extensibility of OAuth2 and instead bind you to a pattern-enforcing framework with almost no possibilities for extension.
42+
43+
Fosite was written because [Hydra](https://github.com/ory-am/hydra) required a more secure and extensible OAuth2 library
44+
then the one it was using.
45+
46+
## Good to know
47+
48+
Fosite is in early development. We will use gopkg for releasing new versions of the API.
49+
Be aware that "go get github.com/ory-am/fosite" will give you the master branch, which is and always will be *unstable*.
50+
Once releases roll out, you will be able to fetch a specific fosite API version through gopkg.in.
51+
52+
## Security
53+
54+
Fosite has two commandments.
55+
56+
### Encourage security by enforcing it!
57+
58+
#### Secure Tokens
59+
60+
Tokens are generated with a minimum entropy of 256 bit. You can use more, if you want.
61+
62+
#### No state, no token
63+
64+
Without a random-looking state, *GET /oauth2/auth* will fail.
65+
66+
#### Opaque tokens
67+
68+
Token generators should know nothing about the request or context.
69+
70+
#### Advanced Token Validation
71+
72+
Tokens are layouted as `<key>.<signature>`. The following workflow requires an attacker to gain
73+
74+
a. access to the database
75+
b. write permission in the persistent store,
76+
c. get hold of the token encryption secret.
77+
78+
A database leak or (exclusively) the knowledge of the token encrpytion secret are not enough to maliciously obtain or create a valid token. Tokens and credentials can
79+
however still be stolen by man-in-the-middle attacks, by malicious or vulnerable clients and other attack vectors.
80+
* Issuance
81+
1. The key is hashed using BCrypt (variable) and used as `<signature>`.
82+
2. The client is presented with `<key>.<signature>`.
83+
3. The signature is encrypted and stored in the database using AES (variable).
84+
* Validation
85+
1. The client presents `<key>.<signature>`.
86+
2. It is validated if <key> matches <signature> using BCrypt (variable).
87+
3. The signature is encrypted using AES (variable).
88+
4. The encrypted signature is looked up in the database, failing validation if no such row exists.
89+
5. They key is considered valid and is now subject for other validations, like audience, redirect or state matching.
90+
91+
#### Encrypt credentials at rest
92+
93+
Credentials (tokens, passwords and secrets) are always encrypted at rest.
94+
95+
#### Implement peer reviewed IETF Standards
96+
97+
Fosite implements [rfc6749](https://tools.ietf.org/html/rfc6749) and enforces countermeasures suggested in [rfc6819](https://tools.ietf.org/html/rfc6819).
98+
99+
### Provide extensibility and interoperability
100+
101+
... because OAuth2 is an extensible and flexible **framework**. Fosite let's you register new response types, new grant
102+
types and new response key value pares. This is useful, if you want to provide OpenID Connect on top of your
103+
OAuth2 stack. Or custom assertions, what ever you like and as long as it is secure. ;)
104+
105+
### Tokens
106+
107+
Tokens are formatted as `<key>.<signature>`. This is beneficial if you want to keep tokens encrypted at rest.
108+
To validate a token in a OAuth2 grant, you could first check if the key matches the signature and then lookup the signature
109+
in your persistent storage (e.g. MySQL). If your persistent storage is intruded (e.g. by SQL injection), an attacker would
110+
only have access to the token signatures and would be, because he does not know the key, unable to use them for authorization.
111+
112+
A token generated by `generator.CryptoGenerator` looks like:
113+
114+
```
115+
GUULhK6Od/7UAlnKvMau8APHSKXSRwm9aoOk56SHBns.JDJhJDEwJDdwVmpCQmJLYzM2VDg1VHJ5aEdVOE81NVdRSkt6bHBHR1QwOC9pbTNFWmpQRXliTWRPeDQy
116+
```
117+
118+
## Usage
119+
120+
This section is WIP and we welcome discussions via PRs or in the issues.
121+
122+
### Store
123+
124+
### Authorize Endpoint
125+
126+
```go
127+
var r *http.Request // we're assuming that we are inside a http.Handler
128+
var rw http.ResponseWriter // we're assuming that we are inside a http.Handler
129+
130+
var store fosite.Storage // needs to be implemented or by using some library
131+
config := fosite.NewDefaultConfig()
132+
oauth := fosite.NewOAuth(config)
133+
authorizeRequest, err := oauth.NewAuthorizeRequest(r, store)
134+
if err != nil {
135+
oauth.RedirectError(rw, error)
136+
// or, for example: oauth.WriteError(rw, error)
137+
return
138+
}
139+
140+
// you have now access to authorizeRequest.Scope, ...Code ...ResponseTypes ...Scopes ...
141+
142+
// decide what to do based on scope and response type
143+
// e.g: response, err = oauth.HandleAuthorizeRequest(authorizeRequest)
144+
145+
// set up a session
146+
// session := oauth2.NewAuthorizeSession(123)
147+
// session.SetExtra(extra interface{})
148+
149+
// persist that stuff in the database
150+
// err = oauth2.PersistAuthorizeRequest(authorizeRequest, session) // sets e.g. session.Persistent = true
151+
152+
// finally, persist code in store and send response
153+
// e.g: oauth2.WriteResponse(rw, response, session)
154+
```
155+
156+
Because each component returns a different type, we can be (if safeguards are installed) quite sure, that the developer
157+
implemented the work flow the right way:
158+
159+
1. `NewAuthorizeRequest(args...) *AuthorizeRequest`: Fetch authorize request information
160+
2. do whatever you like
161+
3. `HandleAuthorizeRequest(args...) *AuthorizeResponse`: Handle authorize request (check scopes and response types, hydrate response...)
162+
4. do whatever you like
163+
5. `oauth2.NewAuthorizeSession(*AuthorizeResponse) *AuthorizeSession`: A session
164+
6. do whatever you like, e.g. `session.SetExtra(map[string]interface{"foo": "bar"})`
165+
7. `oauth2.PersistAuthorizeRequest` persists the request in the database so the token endpoint can look up information
166+
8. do whatever you like
167+
9. `oauth2.WriteResponse(rw, response, session)` to write the response
168+
10. done.
169+
170+
It is not clear yet how HandleAuthorizeRequest could be extensible. It might be possible to introduce an interface like AuthorizeStrategy
171+
and implement different strategies like IDTokenStrategy, AuthorizeCodeStrategy, AccessTokenStrategy.
172+
What could be tricky though is to define a good response / result model because the strategies be very different in execution logic and requirements.
173+
174+
### OpenID Connect
175+
176+
### Token Endpoint

0 commit comments

Comments
 (0)