Golang OAuth2 server library

OSIN

GoDoc

Golang OAuth2 server library

OSIN is an OAuth2 server library for the Go language, as specified at http://tools.ietf.org/html/rfc6749 and http://tools.ietf.org/html/draft-ietf-oauth-v2-10.

It also includes support for PKCE, as specified at https://tools.ietf.org/html/rfc7636, which increases security for code-exchange flows for public OAuth clients.

Using it, you can build your own OAuth2 authentication service.

The library implements the majority of the specification, like authorization and token endpoints, and authorization code, implicit, resource owner and client credentials grant types.

Example Server

import (
	"github.com/openshift/osin"
	ex "github.com/openshift/osin/example"
)

// ex.NewTestStorage implements the "osin.Storage" interface
server := osin.NewServer(osin.NewServerConfig(), ex.NewTestStorage())

// Authorization code endpoint
http.HandleFunc("/authorize", func(w http.ResponseWriter, r *http.Request) {
	resp := server.NewResponse()
	defer resp.Close()

	if ar := server.HandleAuthorizeRequest(resp, r); ar != nil {

		// HANDLE LOGIN PAGE HERE

		ar.Authorized = true
		server.FinishAuthorizeRequest(resp, r, ar)
	}
	osin.OutputJSON(resp, w, r)
})

// Access token endpoint
http.HandleFunc("/token", func(w http.ResponseWriter, r *http.Request) {
	resp := server.NewResponse()
	defer resp.Close()

	if ar := server.HandleAccessRequest(resp, r); ar != nil {
		ar.Authorized = true
		server.FinishAccessRequest(resp, r, ar)
	}
	osin.OutputJSON(resp, w, r)
})

http.ListenAndServe(":14000", nil)

Example Access

Open in your web browser:

http://localhost:14000/authorize?response_type=code&client_id=1234&redirect_uri=http%3A%2F%2Flocalhost%3A14000%2Fappauth%2Fcode

Storage backends

There is a mock available at example/teststorage.go which you can use as a guide for writing your own.

You might want to check out other implementations for common database management systems as well:

License

The code is licensed using "New BSD" license.

Author

Rangel Reale [email protected]

Changes

2019-05-13

  • NON-BREAKING CHANGES
    • Updated imports in examples to use github.com/openshift/osin instead of github.com/RangelReale/osin

2014-06-25

  • BREAKING CHANGES:
    • Storage interface has 2 new methods, Clone and Close, to better support storages that need to clone / close in each connection (mgo)

    • Client was changed to be an interface instead of an struct. Because of that, the Storage interface also had to change, as interface is already a pointer.

    • HOW TO FIX YOUR CODE:

      • In your Storage, add a Clone function returning itself, and a do nothing Close.

      • In your Storage, replace all *osin.Client with osin.Client (remove the pointer reference)

      • If you used the osin.Client struct directly in your code, change it to osin.DefaultClient, which is a struct with the same fields that implements the interface.

      • Change all accesses using osin.Client to use the methods instead of the fields directly.

      • You MUST defer Response.Close in all your http handlers, otherwise some Storages may not clean correctly.

          resp := server.NewResponse()
          defer resp.Close()
        
Owner
OpenShift
The developer and operations friendly Kubernetes distro
OpenShift
Comments
  • Deprecating the project

    Deprecating the project

    Hello,

    As everyone can see, this project is not updated for a long time. Because of a lack of time, I am not finding time to review all issues/pull requests, and it is very important to review all carefully because bugs on this kind of library can have serious consequences.

    Also OAuth best practices and extensions appear all the time, so this kind of library requires constant attention, which I cannot commit at this time.

    So I am thinking of deprecating this project, mark it as readonly, and recommend other libraries on the README to warn people still coming here.

    Looks like the better maintaned library is "ory/fosite", which as I remember started as a fork of OSIN (I think). Can someone recommend other libraries that I can link to?

  • rfc6819: No cleartext storage of credentials

    rfc6819: No cleartext storage of credentials

    5.1.4.1.3. No Cleartext Storage of Credentials The authorization server should not store credentials in clear text. Typical approaches are to store hashes instead or to encrypt credentials. If the credential lacks a reasonable entropy level (because it is a user password), an additional salt will harden the storage to make offline dictionary attacks more difficult. Note: Some authentication protocols require the authorization server to have access to the secret in the clear. Those protocols cannot be implemented if the server only has access to hashes. Credentials should be strongly encrypted in those cases.

    OAuth 2.0 Threat Model and Security Considerations

    Gaining access to the database, e.g. by using SQL Injection (OWASP's #1 attack vector), would provide an attacker with long lived credentials (refresh tokens) and short lived credentials (authorize code, access token). Having client passwords stored securely is nice and all but gives a false sense of security, because all other credentials are stored in a insecure way.

    Right now, a storage could implement encryption and en-/decrypt tokens on SaveAccess / LoadAccess / etc. In an ideal world, we should not rely on encryption but rather on hashing, but that option is currently not possible in a performant way unless unsalted md5 / crc32 / shaXYZ is used. Unsalted hashing is considered bad practice for long living credentials (:= refresh tokens).

    Ideally, a token would consist of two parts: {random-string-without-dots}.{signature} Only the signature is stored. The authorization server would then first validate if random-string matches signature (e.g. by using BCrypt) and reject the token/code if the two mismatch. It would then lookup the signature in the database confirming that the token/code exists and return the appropriate data. An attacker who gained access to the database would then only have the signature which is useless without the random-string. With BCrypt it would practically be impossible to find the matching random-string in a reasonable time.

    If encryption (AES) was used, an attacker who gained access to both database and app server would have access to the encryption key, rendering the security measure insecure. If hashing is used, there is no way to guess the credentials, even if an attacker has access to both systems. Only changes to the code base might disable these security measures. These however will probably be catched by a sysadmin in reasonable time.

    Yes, this could be implemented by providing a custom store implementation and token generation strategy. But the store would become a validator and suddenly be more than just storage. Additionally, you can not use any of the storage implementations listed in the readme. Plus this library should enforce secure behavior rather than making insecure behavior so easy to get right.

    I fell into that pitfall and it will take me significant time to refactor it and get security right. And seeing how popular this repository is amongst gophers I have reasonable doubt that some applications / companies out there are not as secure as they claim or think.

  • BREAKING CHANGES proposal, please review

    BREAKING CHANGES proposal, please review

    I am proposing these breaking changes, that should improve the interface of the library. If you are using the library, please review these and comment if you see any trouble with them.

    • Change Client to be an interface (allows more secure Secret Handling)
    • Add Clone and Close methods to Storage (for storages that need to be cloned each call, e.g. mgo)
    • Add Close method to Response and required it to be closed with defer on use (to cleanup the Storage)
    • BREAKING CHANGES:
      • Storage interface has 2 new methods, Clone and Close, to better support storages that need to clone / close in each connection (mgo)
      • Client was changed to be an interface instead of an struct. Because of that, the Storage interface also had to change, as interface is already a pointer.
      • HOW TO FIX YOUR CODE:
        • In your Storage, add a Clone function returning itself, and a do nothing Close.

        • In your Storage, replace all *osin.Client with osin.Client (remove the pointer reference)

        • If you used the osin.Client struct directly in your code, change it to osin.DefaultClient, which is a struct with the same fields that implements the interface.

        • Change all accesses using osin.Client to use the methods instead of the fields directly.

        • You MUST defer Response.Close in all your http handlers, otherwise some Storages may not clean correctly.

            resp := server.NewResponse()
            defer resp.Close()
          
  • Client secret required for password grant type

    Client secret required for password grant type

    Reading through RFC (4.3) I could not find a clear and direct statement about client secret -- is it optional or required. OSIN makes it required (judging by logic in getClientAuth()) but changing that and make this configurable would be trivial.

    I havn't done any extensive research, but for example, PHP's implementation (https://github.com/bshaffer/oauth2-server-php) allows client secrets to be optional. A few other examples: http://security.stackexchange.com/questions/64091/oauth2-resource-owner-password-credentials-grant, https://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified#web-server-apps

    My opinion is that both functions, CheckBasicAuth() and getClientAuth() take too much responsibility in validating of the credentials. This should be responsibility of some other (pluggable) function (similar as ClientSecretMatcher solution)

    Any thoughts on that?

  • Add a default salted Password implementation + Testing + Small code improvement.

    Add a default salted Password implementation + Testing + Small code improvement.

    • add a default salted Password implementation in client.go
    • the new Implementation is tested in client_test.go
    • reduce and improce utilitise function in urlvalidate.go
  • add Context support for storage in a backwards compatible manner.

    add Context support for storage in a backwards compatible manner.

    This fixes https://github.com/RangelReale/osin/issues/139

    Basically this allows context.Context of http.Request to be propagaded to the Backend. If your server has a deadlien for requests, this means that your storage will obey these requests (e.g. deadlines, cancellation).

    We currently need it for Go 1.7, since we have a Storage relying on Google Datastore (which uses gRPC and Context cancellation). For Go 1.8 the database/sql packages will support cancellable queries: https://tylerchr.blog/golang-18-whats-coming/

    This change adds StorageWithContext to avoid breaking compatibility with users implementing Storage. If a Storage is used, a StorageWithContext adapter is used.

  • Add helpful internal errors.

    Add helpful internal errors.

    This PR improves debuggability of osin by adding an InternalError to common missing parameters.

    These errors (except for required URL parameters: code, refresh_token) are not surfaced to the users and are just added as an InternalError for the caller to operate on (e.g. log).

  • Remove* errors are ignored

    Remove* errors are ignored

  • redirect_url vs redirect_uri

    redirect_url vs redirect_uri

    I'm not sure what the oauth official param is but I noticed on Google's OAuth API they use redirect_uri. Should this be something you can customize? Also, I noticed in the README it says to use redirect_url, and when I use that URL, that seems to work and not redirect_uri using osin. I did a search of the entire repo on osin and I don't see how redirect_url even works and not redirect_uri. Any ideas?

  • Proposed changes for GAE compatibility

    Proposed changes for GAE compatibility

    To make osin compatible with Google App Engine, the http request needed to be pass in to Storage. Therefore these breaking change.

    • Change Storage.Clone() to require a *http.Request This breaks previous implementation of Storage interface
    • Change NewResponse() and Server.NewResponse() to require a *http.Request. This breaks previous code uses these interfaces.
    • Change NewResponse() and Server.NewResponse() to pass the *http.Request to Storage.Clone()

    This pull request fixes #28.

  • Allow salted client secrets

    Allow salted client secrets

    This allows clients to implement an interface which gives them control over determining whether a secret matches. This enables encrypted/salted client secret storage, instead of assuming the original client secret can be extracted. It also allows rotation of secrets, where multiple secrets are considered valid concurrently.

    This is done as an optional interface and interface check to remain backwards-compatible with the existing Client interface.

  • the project active?

    the project active?

    last commit was made day Oct 25, 2019, more than 1 year ago, the project is listed in awesome-go and we have software checking inactive projects to remove from the list if it is not active

    ref: https://github.com/avelino/awesome-go/issues/3316

  • Future Release Branches Frozen For Merging | branch:release-4.13 branch:release-4.14

    Future Release Branches Frozen For Merging | branch:release-4.13 branch:release-4.14

    The following branches are being fast-forwarded from the current development branch (master) as placeholders for future releases. No merging is allowed into these release branches until they are unfrozen for production release.

    • release-4.13
    • release-4.14

    For more information, see the branching documentation.

  • Change to Storage interface to accept context interface

    Change to Storage interface to accept context interface

    I would like to modify the storage interface to accept an interface for context information.

    i.e.

    // GetClient loads the client by id (client_id)
    GetClient(context interface{}, id string) (Client, error)
    

    It would also require changes to the response to accept a Context to be included in the response that could be passed into the storage calls.

    // Server response
    type Response struct {
        Context            interface{}
    

    This would be a breaking change. Would this be considered for a merge?

Hazelcast Storage for go-oauth2/oauth2

Hazelcast Storage for go-oauth2/oauth2

Jan 26, 2022
Golang OAuth2 server library

OSIN Golang OAuth2 server library OSIN is an OAuth2 server library for the Go language, as specified at http://tools.ietf.org/html/rfc6749 and http://

Dec 23, 2022
Go library providing in-memory implementation of an OAuth2 Authorization Server / OpenID Provider

dispans Go library providing in-memory implementation of an OAuth2 Authorization Server / OpenID Provider. The name comes from the Swedish word dispen

Dec 22, 2021
A standalone, specification-compliant, OAuth2 server written in Golang.
A standalone, specification-compliant,  OAuth2 server written in Golang.

Go OAuth2 Server This service implements OAuth 2.0 specification. Excerpts from the specification are included in this README file to describe differe

Dec 28, 2022
Golang OAuth2.0 server

Golang OAuth2.0 server

Aug 24, 2022
A Sample Integration of Google and GitHub OAuth2 in Golang (GoFiber) utilising MongoDB

Go Oauth Server This is sample OAuth integration written in GoLang that also uses MongoDB. This is a sample TODO Application where people can Create a

Dec 27, 2022
Go login handlers for authentication providers (OAuth1, OAuth2)
Go login handlers for authentication providers (OAuth1, OAuth2)

gologin Package gologin provides chainable login http.Handler's for Google, Github, Twitter, Facebook, Bitbucket, Tumblr, or any OAuth1 or OAuth2 auth

Dec 30, 2022
JWT login microservice with plugable backends such as OAuth2, Google, Github, htpasswd, osiam, ..
JWT login microservice with plugable backends such as OAuth2, Google, Github, htpasswd, osiam, ..

loginsrv loginsrv is a standalone minimalistic login server providing a JWT login for multiple login backends. ** Attention: Update to v1.3.0 for Goog

Dec 24, 2022
Go OAuth2

OAuth2 for Go oauth2 package contains a client implementation for OAuth 2.0 spec. Installation go get golang.org/x/oauth2 Or you can manually git clo

Jan 8, 2023
Envoy Oauth2 Filter helloworld
Envoy Oauth2 Filter helloworld

Envoy Oauth2 Filter A simple sample demonstrating Envoy's Oauth2 Filter. Basically, this filter will handle all the details for OAuth 2.0 for Web Serv

Jan 2, 2023
Identity-service - An OAuth2 identity provider that operates over gRPC

Identity-service - An OAuth2 identity provider that operates over gRPC

May 2, 2022
Identity - An OAuth2 identity provider that operates over gRPC

Otter Social > Identity Provider An OAuth2 identity provider that operates over

May 2, 2022
JWT login microservice with plugable backends such as OAuth2, Google, Github, htpasswd

login-service login-service is a standalone minimalistic login server providing a (JWT)[https://jwt.io/] login for multiple login backends. Abstract l

Feb 12, 2022
HTTP-server-with-auth# HTTP Server With Authentication

HTTP-server-with-auth# HTTP Server With Authentication Introduction You are to use gin framework package and concurrency in golang and jwt-go to imple

Nov 9, 2022
A library for Go client applications that need to perform OAuth authorization against a server
A library for Go client applications that need to perform OAuth authorization against a server

oauth-0.8.0.zip oauth A library for Go client applications that need to perform OAuth authorization against a server, typically GitHub.com. Traditiona

Oct 13, 2021
Example of a simple application which is powered by a third-party oAuth 2.0 server for it's authentication / authorization. Written in Golang.

go mod init github.com/bartmika/osin-thirdparty-example go get github.com/spf13/cobra go get github.com/openshift/osin go get github.com/openshift/osi

Jan 4, 2022
[NO LONGER MAINTAINED} oauth 2 server implementation in Go

hero hero is a feature rich oauth 2 server implementation in Go. Features User account management Client management oauth 2 rfc 6749 compliant Configu

Nov 18, 2022
Authentication server for Docker Registry 2

The original Docker Registry server (v1) did not provide any support for authentication or authorization. Access control had to be performed externally, typically by deploying Nginx in the reverse proxy mode with Basic or other type of authentication. While performing simple user authentication is pretty straightforward, performing more fine-grained access control was cumbersome.

Jan 2, 2023
Jan 9, 2023