Code Monkey home page Code Monkey logo

fosite's Introduction

ORY Fosite - Security-first OAuth2 framework

Build Status Coverage Status Go Report Card

Join the chat at https://www.ory.sh/chat

The security first OAuth2 & OpenID Connect framework for Go. Built simple, powerful and extensible. This library implements peer-reviewed IETF RFC6749, counterfeits weaknesses covered in peer-reviewed IETF RFC6819 and countermeasures various database attack scenarios, keeping your application safe when that hacker penetrates or leaks your database. OpenID Connect is implemented according to OpenID Connect Core 1.0 incorporating errata set 1 and includes all flows: code, implicit, hybrid.

This library considered and implemented:

OAuth2 and OpenID Connect are difficult protocols. If you want quick wins, we strongly encourage you to look at Hydra. Hydra is a secure, high performance, cloud native OAuth2 and OpenID Connect service that integrates with every authentication method imaginable and is built on top of Fosite.

Table of Contents

Motivation

Fosite was written because our OAuth2 and OpenID Connect service Hydra required a secure and extensible OAuth2 library. We had to realize that nothing matching our requirements was out there, so we decided to build it ourselves.

API Stability

The core public API is almost stable as most changes will only touch the inner workings.

We strongly encourage vendoring fosite using dep or comparable tools.

Example

The example does not have nice visuals but it should give you an idea of what you can do with Fosite and a few lines of code.

Authorize Code Grant

You can run this minimalistic example by doing

go get github.com/ory/fosite-example
cd $GOPATH/src/github.com/ory/fosite-example
dep ensure
go install github.com/ory/fosite-example
fosite-example

There should be a server listening on localhost:3846. You can check out the example's source code here.

A word on quality

We tried to set up as many tests as possible and test for as many cases covered in the RFCs as possible. But we are only human. Please, feel free to add tests for the various cases defined in the OAuth2 RFCs 6749 and 6819 or any other cases that improve the tests.

Everyone writing an RFC conform test that breaks with the current implementation, will receive a place in the Hall of Fame!

A word on security

Please be aware that Fosite only secures parts of your server side security. You still need to secure your apps and clients, keep your tokens safe, prevent CSRF attacks, ensure database security, use valid and strong TLS certificates and much more. If you need any help or advice feel free to contact our security staff through our website!

We have given the various specifications, especially OAuth 2.0 Threat Model and Security Considerations, a very close look and included everything we thought was in the scope of this framework. Here is a complete list of things we implemented in Fosite:

Additionally, we added these safeguards:

  • Enforcing random states: Without a random-looking state or OpenID Connect nonce the request will fail.
  • Advanced Token Validation: Tokens are layouted as <key>.<signature> where <signature> is created using HMAC-SHA256 using a global secret. This is what a token can look like: /tgBeUhWlAT8tM8Bhmnx+Amf8rOYOUhrDi3pGzmjP7c=.BiV/Yhma+5moTP46anxMT6cWW8gz5R5vpC9RbpwSDdM=

Sections below Section 5 that are not covered in the list above should be reviewed by you. If you think that a specific section should be something that is covered in Fosite, feel free to create an issue. Please be aware that OpenID Connect requires specific knowledge of the identity provider, which is why Fosite only implements core requirements and most things must be implemented by you (for example prompt, max_age, ui_locales, id_token_hint, user authentication, session management, ...).

It is strongly encouraged to use the handlers shipped with Fosite as they follow the specs and are well tested.

A word on extensibility

Fosite is extensible ... because OAuth2 is an extensible and flexible framework. Fosite let's you register custom token and authorize endpoint handlers with the security that the requests have been validated against the OAuth2 specs beforehand. You can easily extend Fosite's capabilities. For example, if you want to provide OpenID Connect on top of your OAuth2 stack, that's no problem. Or custom assertions, what ever you like and as long as it is secure. ;)

Installation

Go 1.11+ must be installed on your system and it is required that you have set up your GOPATH environment variable.

go get -u github.com/ory/fosite/...

We recommend to use dep to mitigate compatibility breaks that come with new api versions.

Documentation

There is an API documentation available at godoc.org/ory/fosite.

Scopes

Fosite has three strategies for matching scopes. You can replace the default scope strategy if you need a custom one by implementing fosite.ScopeStrategy.

Using the composer, setting a strategy is easy:

import "github.com/ory/fosite"

var config = &fosite.Config{
ScopeStrategy: fosite.HierarchicScopeStrategy,
}

Note: To issue refresh tokens with any of the grants, you need to include the offline scope in the OAuth2 request. This can be modified by the RefreshTokenScopes compose configuration. When set to an empty array, all grants will issue refresh tokens.

fosite.WildcardScopeStrategy

This is the default strategy, and the safest one. It is best explained by looking at some examples:

  • users.* matches users.read
  • users.* matches users.read.foo
  • users.read matches users.read
  • users does not match users.read
  • users.read.* does not match users.read
  • users.*.* does not match users.read
  • users.*.* matches users.read.own
  • users.*.* matches users.read.own.other
  • users.read.* matches users.read.own
  • users.read.* matches users.read.own.other
  • users.write.* does not match users.read.own
  • users.*.bar matches users.baz.bar
  • users.*.bar does not users.baz.baz.bar

To request users.*, a client must have exactly users.* as granted scope.

fosite.ExactScopeStrategy

This strategy is searching only for exact matches. It returns true iff the scope is granted.

fosite.HierarchicScopeStrategy

This strategy is deprecated, use it with care. Again, it is best explained by looking at some examples:

  • users matches users
  • users matches users.read
  • users matches users.read.own
  • users.read matches users.read
  • users.read matches users.read.own
  • users.read does not match users.write
  • users.read does not match users.write.own

Globalization

Fosite does not natively carry translations for error messages and hints, but offers an interface that allows the consumer to define catalog bundles and an implementation to translate. This is available through the MessageCatalog interface. The functions defined are self-explanatory. The DefaultMessageCatalog illustrates this. Compose config has been extended to take in an instance of the MessageCatalog.

Building translated files

There are three possible "message key" types:

  1. Value of RFC6749Error.ErrorField: This is a string like invalid_request and correlates to most errors produced by Fosite.
  2. Hint identifier passed into RFC6749Error.WithHintIDOrDefaultf: This func is not used extensively in Fosite but, in time, most WithHint and WithHintf will be replaced with this function.
  3. Free text string format passed into RFC6749Error.WithHint and RFC6749Error.WithHintf: This function is used in Fosite and Hydra extensively and any message catalog implementation can use the format string parameter as the message key.

An example of a message catalog can be seen in the i18n_test.go.

Generating the en messages file

This is a WIP at the moment, but effectively any scripting language can be used to generate this. It would need to traverse all files in the source code and extract the possible message identifiers based on the different message key types.

Quickstart

Instantiating fosite by hand can be painful. Therefore we created a few convenience helpers available through the compose package. It is strongly encouraged to use these well tested composers.

In this very basic example, we will instantiate fosite with all OpenID Connect and OAuth2 handlers enabled. Please refer to the example app for more details.

This little code snippet sets up a full-blown OAuth2 and OpenID Connect example.

package main

import "github.com/ory/fosite"
import "github.com/ory/fosite/compose"
import "github.com/ory/fosite/storage"

// This is the example storage that contains:
// * an OAuth2 Client with id "my-client" and secrets "foobar" and "foobaz" capable of all oauth2 and open id connect grant and response types.
// * a User for the resource owner password credentials grant type with username "peter" and password "secret".
//
// You will most likely replace this with your own logic once you set up a real world application.
var storage = storage.NewExampleStore()

// This secret is being used to sign access and refresh tokens as well as
// authorization codes. It must be exactly 32 bytes long.
var secret = []byte("my super secret signing password")

privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
panic("unable to create private key")
}

// check the api docs of fosite.Config for further configuration options
var config = &fosite.Config{
	AccessTokenLifespan: time.Minute * 30,
	GlobalSecret: secret,
	// ...
}

var oauth2Provider = compose.ComposeAllEnabled(config, storage, privateKey)

// The authorize endpoint is usually at "https://mydomain.com/oauth2/auth".
func authorizeHandlerFunc(rw http.ResponseWriter, req *http.Request) {
	// This context will be passed to all methods. It doesn't fulfill a real purpose in the standard library but could be used
	// to abort database lookups or similar things.
	ctx := req.Context()

	// Let's create an AuthorizeRequest object!
	// It will analyze the request and extract important information like scopes, response type and others.
	ar, err := oauth2Provider.NewAuthorizeRequest(ctx, req)
	if err != nil {
		oauth2Provider.WriteAuthorizeError(ctx, rw, ar, err)
		return
	}

	// Normally, this would be the place where you would check if the user is logged in and gives his consent.
	// We're simplifying things and just checking if the request includes a valid username and password
	if req.Form.Get("username") != "peter" {
		rw.Header().Set("Content-Type", "text/html;charset=UTF-8")
		rw.Write([]byte(`<h1>Login page</h1>`))
		rw.Write([]byte(`
			<p>Howdy! This is the log in page. For this example, it is enough to supply the username.</p>
			<form method="post">
				<input type="text" name="username" /> <small>try peter</small><br>
				<input type="submit">
			</form>
		`))
		return
	}

	// Now that the user is authorized, we set up a session. When validating / looking up tokens, we additionally get
	// the session. You can store anything you want in it.

	// The session will be persisted by the store and made available when e.g. validating tokens or handling token endpoint requests.
	// The default OAuth2 and OpenID Connect handlers require the session to implement a few methods. Apart from that, the
	// session struct can be anything you want it to be.
	mySessionData := &fosite.DefaultSession{
		Username: req.Form.Get("username"),
	}

	// It's also wise to check the requested scopes, e.g.:
	// if authorizeRequest.GetScopes().Has("admin") {
	//     http.Error(rw, "you're not allowed to do that", http.StatusForbidden)
	//     return
	// }

	// Now we need to get a response. This is the place where the AuthorizeEndpointHandlers kick in and start processing the request.
	// NewAuthorizeResponse is capable of running multiple response type handlers which in turn enables this library
	// to support open id connect.
	response, err := oauth2Provider.NewAuthorizeResponse(ctx, ar, mySessionData)
	if err != nil {
		oauth2Provider.WriteAuthorizeError(ctx, rw, ar, err)
		return
	}

	// Awesome, now we redirect back to the client redirect uri and pass along an authorize code
	oauth2Provider.WriteAuthorizeResponse(ctx, rw, ar, response)
}

// The token endpoint is usually at "https://mydomain.com/oauth2/token"
func tokenHandlerFunc(rw http.ResponseWriter, req *http.Request) {
	ctx := req.Context()

	// Create an empty session object that will be passed to storage implementation to populate (unmarshal) the session into.
	// By passing an empty session object as a "prototype" to the store, the store can use the underlying type to unmarshal the value into it.
	// For an example of storage implementation that takes advantage of that, see SQL Store (fosite_store_sql.go) from ory/Hydra project.
	mySessionData := new(fosite.DefaultSession)

	// This will create an access request object and iterate through the registered TokenEndpointHandlers to validate the request.
	accessRequest, err := oauth2Provider.NewAccessRequest(ctx, req, mySessionData)
	if err != nil {
		oauth2Provider.WriteAccessError(ctx, rw, accessRequest, err)
		return
	}

	if mySessionData.Username == "super-admin-guy" {
		// do something...
	}

	// Next we create a response for the access request. Again, we iterate through the TokenEndpointHandlers
	// and aggregate the result in response.
	response, err := oauth2Provider.NewAccessResponse(ctx, accessRequest)
	if err != nil {
		oauth2Provider.WriteAccessError(ctx, rw, accessRequest, err)
		return
	}

	// All done, send the response.
	oauth2Provider.WriteAccessResponse(ctx, rw, accessRequest, response)

	// The client has a valid access token now
}

func someResourceProviderHandlerFunc(rw http.ResponseWriter, req *http.Request) {
	ctx := req.Context()
	requiredScope := "blogposts.create"

	_, ar, err := oauth2Provider.IntrospectToken(ctx, fosite.AccessTokenFromRequest(req), fosite.AccessToken, new(fosite.DefaultSession), requiredScope)
	if err != nil {
		// ...
	}

	// If no error occurred the token + scope is valid and you have access to:
	// ar.GetClient().GetID(), ar.GetGrantedScopes(), ar.GetScopes(), ar.GetSession().UserID, ar.GetRequestedAt(), ...
}

Code Examples

Fosite provides integration tests as well as a http server example:

  • Fosite ships with an example app that runs in your browser: Example app.
  • If you want to check out how to enable specific handlers, check out the integration tests.

If you have working examples yourself, please share them with us!

Example Storage Implementation

Fosite does not ship a storage implementation. This is intended, because requirements vary with every environment. You can find a reference implementation at storage/memory.go. This storage fulfills requirements from all OAuth2 and OpenID Connect handlers.

Extensible handlers

OAuth2 is a framework. Fosite mimics this behaviour by enabling you to replace existing or create new OAuth2 handlers. Of course, fosite ships handlers for all OAuth2 and OpenID Connect flows.

This section is missing documentation and we welcome any contributions in that direction.

JWT Introspection

Please note that when using the OAuth2StatelessJWTIntrospectionFactory access token revocation is not possible.

Contribute

You need git and golang installed on your system.

go get -d github.com/ory/fosite
cd $GOPATH/src/github.com/ory/fosite
git status
git remote add myfork <url-to-your-fork>
go test ./...

Simple, right? Now you are ready to go! Make sure to run go test ./... often, detecting problems with your code rather sooner than later. Please read [CONTRIBUTE.md] before creating pull requests and issues.

Refresh mock objects

Run ./generate-mocks.sh in fosite's root directory or run the contents of [generate-mocks.sh] in a shell.

Hall of Fame

This place is reserved for the fearless bug hunters, reviewers and contributors (alphabetical order).

Find out more about the author of Fosite and Hydra, and the Ory Company.

fosite's People

Contributors

aaslamin avatar adamdecaf avatar aeneasr avatar ajanthan avatar arekkas avatar beornf avatar ccbrown avatar cristiangraz avatar dependabot[bot] avatar hperl avatar james-d-elliott avatar kevgo avatar kujenga avatar leetal avatar matthewhartstonge avatar michaelboke avatar mitar avatar narg95 avatar nerocrux avatar nikita-v avatar niwenhao avatar phil-davis avatar pjcdawkins avatar pschultz avatar renovate[bot] avatar sawadashota avatar svrakitin avatar vineet-garg avatar vivshankar avatar zepatrik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fosite's Issues

Error response doesn't follow spec

I appreciate this is still under heavy development and this is likely just not implemented yet but thought I'd add it here so that it doesn't get lost, library looks really good so far.

As per the spec:

If the request fails due to a missing, invalid, or mismatching
redirection URI, or if the client identifier is missing or invalid,
the authorization server SHOULD inform the resource owner of the
error and MUST NOT automatically redirect the user-agent to the
invalid redirection URI.

Currently the redirect uri is used for all errors except a missing redirect_uri. Potential attack could be a redirect_uri of javascript:evil(); to perform XSS.

Gitter Chat

Gitter is a nice way for developers to talk about a certain project. There's currently a gitter chat for hydra (built on fosite) but not one yet for fosite. I'm opening this issue to discuss the possibility of having a gitter chat for fosite.

OpenID Connect audit

Fosite's vision is to be a security first framework for OAuth2 related standards. I can not audit everything on my own, so I need your help to find issues and missing features which are required for this vision.

Return context

Hi! I have special case for returning some additional signatures from such methods like CreateAccessTokenSession.
And I have just added a return context for ALL endpoints & storages. For example:

type AuthorizeCodeStorage interface {
    CreateAuthorizeCodeSession(
        ctx context.Context,
        code string,
        request fosite.Requester,
    ) (context.Context, error)

    GetAuthorizeCodeSession(
        ctx context.Context,
        code string,
        session interface{},
    ) (context.Context, fosite.Requester, error)

    DeleteAuthorizeCodeSession(
        ctx context.Context,
        code string,
    ) (context.Context, error)
}

All tests passes!
Do you interest in that functionality?

Composable factory for fosite

Something along the lines of:

config := fosite.ComposeConfig{
    AccessTokenLifespan
    IDTokenLifespan
    // ....
}

oauth2 := fosite.Compose(
   fosite.NewMemoryStore(),
   // order matters...
   fosite.NewAuthorizeCodeHandler(config),
   fosite.NewRefreshCodeHandler(config), // will additionally register validators too
   // ...
)

and convenience stuff like:

oauth2 := fosite.ComposeEverythingEnabled(fosite.NewMemoryStore(), config)

Update jwt-go depdenceny

src/github.com/ory-am/fosite/token/jwt/jwt.go:29: cannot use claims.ToMap() (type map[string]interface {}) as type jwt.Claims in assignment:
map[string]interface {} does not implement jwt.Claims (missing Valid method)

Installation fails on go 1.5.3

I tried following the readme and install the v0 branch with the following command:
go get gopkg.in/ory-am/fosite.v0/...

This results in the following error:
package gopkg.in/ory-am/fosite.v0/fosite-example imports github.com/ory-am/fosite/fosite-example/internal: use of internal package not allowed

This works:
go get gopkg.in/ory-am/fosite.v0/

Is this just a documentation problem?

Thanks for the help

Do you consider this production ready?

The only hint I've seen is this:

"Once releases roll out, you will be able to fetch a specific fosite API version through gopkg.in. As of now, no stable v1 version exists."

OAuth2 audit

Fosite's vision is to be a security first framework for OAuth2 related standards. I can not audit everything on my own, so I need your help to find issues and missing features which are required for this vision.

Storing token/code expiration

I'm trying to implement a storage layer and as #25 mentions it's a little hard without a reference implementation.

How do I store expiration's for the token?

Looking at fosite.Requester it looks like there's no way to get it. I maybe completely missing the point, since I'm very new to this library.

add open id connect handler

Right now, only the core OAuth2 spec is implemented. I want to extend this by an OpenID Connect handler. If you want to give this a shot, I welcome an PRs regarding this. :)

docs: document exemplary management interface

Put this somewhere in the docs:

// Manager defines an optional but recommended API for your fosite storage implementation. This API is not
// consumed by fosite itself. You don not need to implement this library, it is merely a good practice guide.
type Manager interface {
    // CreateClient stores a client or returns an error.
    CreateClient(Client) error

    // UpdateClient updates a client or returns an error.
    UpdateClient(Client) error

// ....
}

Access Token verification

How do I verify validity of a token after getting it from the request header? It's not immediately obvious what the best approach is.

Sorry if this is documented somewhere, I was not able to find it.

Enforce use of scopes?

Scopes are something that is thrown a little bit under the table in most OAuth2 tutorials but scopes are a very important part of OAuth2, as OAuth2 is a delegation protocol for a limited scope. Issuing tokens that are allowed to do anything by default ist bad practice.

Forcing developers to define and use scopes countermeasures that but it is also another thing one has to think about when using this library.

What do you prefer? Making it easy to use scopes or enforcing to use scopes?

Refactor token validation

Token validation is conceptually broken at the moment. Instead, something similar to token introspection should be possible:

var TokenType int

const AccessToken tokenType = 1 // in handler / validation strategy

fosite.Introspect(token string) (fosite.Requester, error)
fosite.IntrospectStrict(token string, tt tokenType) (fosite.Requester, error)

Both iterate through all validators and return true if one of them validated successfully

Remove mandatory scope

A mandatory scope doesn't make a lot of sense. The user consenting is already giving the "core" scope par definition

How to run fosite example in my own folder

For now I just move the fosite example to my own package folder and I am getting the error about the types:

cannot use clientConf (type "golang.org/x/oauth2".Config) as type "github.com/ory-am/fosite/vendor/golang.org/x/oauth2".Config in argument to pkg.HomeHandler

I understand that the error is caused because inside of fosite you are using glide as a dependencies management and it tries to match two differents types but

what is the best path to follow in this case?

Thx

Credentials in request-body as fallback per 2.3.1 of RFC

Section 2.3.1 of the RFC says:

Including the client credentials in the request-body using the two
parameters is NOT RECOMMENDED and SHOULD be limited to clients unable
to directly utilize the HTTP Basic authentication scheme (or other
password-based HTTP authentication schemes). The parameters can only
be transmitted in the request-body and MUST NOT be included in the
request URI.

When using a REST client for mac that support oauth, I realized it was sending client_id and client_secret in the request body rather than via the Authorization header. While it's definitely not recommended for clients to use, does it make sense to have this included as part of the library as a fallback to support that section of the RFC? I'm not sure what the limitation is of sending an Authorization header, but wanted to discuss here before submitting a PR.

If it's something you think would be useful to have as a fallback I have a PR ready to submit with all the tests.

Consider upgrading to jwt-go 3.0.0

Hi Aeneas!

So, i'm still following the development of all your libraries and we've just now started to implement our interfaces against fosite/hydra. It came to a quick halt when we realized that fosite relies upon v2.7.0 of jwt-go, and that we must use 3.0.0 of jwt-go. We also use glide and this is causing a clash since jwt-go have introduced a breaking change by replacing the map[string]interface{} to a jwt.Claims interface (essentially exactly like your jwt_claims.go).

Do you want help fixing this change (more or less just upgrade to 3.0.0 of jwt-go and create a new type that implements the Claims interface in fosite) or is this on your backlog?

Regards
Alexander W

JWT Support

@arekkas Since i'm a big fan of Hydra and also know that Hydra uses JWT, it would probably be good to add support in Fosite for JWT as well. Since JWT is gaining a lot of focus these days you know ;)

I really like the stateless behaviour of JWT and the ability to put arbitary data into it and lastly that you can validate it without a call to the database. That makes it more robust and easy to use in a multi-service environment, where multiple services need to validate the authenticity of a resource owner.

I know that with enigma, there should really be no hussle to do it quickly. Especially since you basically just can drag and drop the JWT folder of Hydra into Fosite and then modify enigma a little to support pluggable token generators.

What do you think? If you need help implementing anything, just shout out. I can help you! ๐Ÿ‘

make the example more readable

The example is not very readable right now and might be confusing to new developers. I gladly accept any PRs that improve the examples :)

enigma: How to sign and verify tokens or let's use HMAC-SHA256

Right now, tokens are going to be saved as a hashed version. I think there should be one more step.

Issuance:

  1. Create random > 128bit key
  2. Create signature by hashing the key with a secret encryption key using HMAC-256)
  3. Use the signature as primary key for the request session end persist it in the store
  4. Issue {base64_encode(key)}.{base64_encode(signature)} to client

Validation:

  1. Decode base64 values
  2. Validate that key matches signature the key and the secret encryption key
  3. Look up key claims (e.g. expiration date or response types) in the store using the signature
  4. Finish request

The secret encryption key should in fact be {global-secret}-{app-secret} making client validation easier and automaticall revoking tokens when secrets are changed.

This has upsides:

  • We could preemptively discgard any tokens that have an invalid signature (and thus remove database workload).
  • Resource servers could validate the tokens if they know the secret key without establishing a network connection.
  • An attacker knowing the secret encryption key would still not be able to restore a token's key from it's signature.
  • An attacker would require the secret encryption key and have somehow gain write permissions on the database to forge and inject a valid token or authorize code.
  • If the secret encryption key is believed to be compromised, changing it will invalidate all tokens including those who are possibliy forged
  • If the mechanism for generating the secret key is believed to be weak, it can be replaced with a new one making all old and insecure tokens invalid
  • If the client secret is changed, all of it's tokens bekome invalid giving the power to handle and invalidate lost client credentials in a timely fashion.

It should be noted that the secret encryption key is replaceable. Clients are expected to handle revoked tokens if they implement OAuth2. Replacing the current secret encryption key with a new one would render all previously generated tokens to become invalid. Clients should handle this by re-authorizing.

The more I think about this, the more I like this idea.

Add documentation on handlers

As pointed out in #28 , handlers are "magic" for newcomers, especially when coming from osin or similar non-extensible OAuth2 frameworks. Handlers however are a key feature in regards to fosite extensibility and should therefore be better documented.

Example validating requests with acess tokens

All of the examples show how to create authorization codes and access tokens, but there is no example to show how to actually verify the access token on an incoming http request. I looked through the library and think the functionality may be missing since it's more than just calling the storage's GetAccessTokenSession, but wanted to discuss first to see if I had missed it.

example doesn't compile

While trying to run the example on your readme, I get the following:

go install github.com/ory-am/fosite/fosite-example
# github.com/ory-am/fosite/enigma
../../go/src/github.com/ory-am/fosite/enigma/hmacsha.go:26: base64.StdEncoding.WithPadding undefined (type *base64.Encoding has no field or method WithPadding)
../../go/src/github.com/ory-am/fosite/enigma/hmacsha.go:26: undefined: base64.NoPadding

Any ideas?

Questions about sessions

In https://github.com/ory-am/fosite#exemplary-authorization-endpoint it says:

// Now it's time to persist some data. This session will be later available to us in the token endpoint.
// So make sure to store things like the user id here.
// The authorize request will be stored additionally, so no need to save scopes or similar things.
sess := &session{User: "peter"}

and in https://github.com/ory-am/fosite#exemplary-token-endpoint:

// Remember the sesion data from before? Yup, that's going to be saved in here!
var mySessionData session

// This will create an access request object and iterate through the registered TokenEndpointHandlers to validate the request.
accessRequest, err := oauth2.NewAccessRequest(ctx, req, &mySessionData)
if err != nil {
    log.Printf("Error occurred in NewAccessRequest: %s\nStack: \n%s", err, err.(*errors.Error).ErrorStack())
    oauth2.WriteAccessError(rw, accessRequest, err)
    return
}

// Now we have access to mySessionData's populated values and can do crazy things.

I want to understand how one would use this session, who is supposed to fill the session with data, the storage?

Improve error stack trace

It is hard to trace errors because most of them are generic. There should be logging or some other sort of error tracing to reduce this.

docs: Fix typos

Good work on the package so far!

I found a few typos in the example code in the README. Below the variables r should be changed to req.

authorizeRequest, err := oauth2.NewAuthorizeRequest(ctx, r)
response, err := oauth2.HandleAuthorizeRequest(ctx, authorizeRequest, r, &mySessionData) 
accessRequest, err := oauth2.NewAccessRequest(ctx, r, &mySessionData)
response, err := oauth2.NewAccessResponse(ctx, accessRequest, r, mySessionData)

Methods of store.go are not being used

First of all many thanks for writing such a great project!

I am willing to use it one of my project but i see, the methods defiened in fosite-example/store/store.go are not being called at all. I put log trace on each method but after running example, i didn't get any log trace.

In real life, anyone will store client and client config in database, but as store methods are not being called, so how do we write database based store.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.