Golang OAuth2 server library

Overview

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()
        
Issues
  • 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?

    opened by RangelReale 20
  • 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.

    lifecycle/rotten 
    opened by aeneasr 16
  • 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()
          
    opened by RangelReale 14
  • 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?

    lifecycle/rotten 
    opened by darh 13
  • 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
    opened by UrielCh 12
  • 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.

    lifecycle/rotten 
    opened by mwitkow 11
  • 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).

    lifecycle/rotten 
    opened by mwitkow 11
  • Remove* errors are ignored

    Remove* errors are ignored

    opened by bodhi 11
  • 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?

    opened by lancecarlson 11
  • 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.

    opened by yookoala 11
  • 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.

    opened by liggitt 10
  • Authorization Code Request Handler always expects client secret to be present

    Authorization Code Request Handler always expects client secret to be present

    The authorization code request handler gets the client id and client secret from the request form values. For PKCE there is not client secret because the client is considered public and may not necessarily have a client secret. The request handler should bypass the check for client secret when code_verifier is a parameter.

    opened by arjunrn 4
  • 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

    lifecycle/frozen 
    opened by avelino 5
  • Future Release Branches Frozen For Merging | branch:release-4.11 branch:release-4.12

    Future Release Branches Frozen For Merging | branch:release-4.11 branch:release-4.12

    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.11
    • release-4.12

    Contact the Test Platform or Automated Release teams for more information.

    lifecycle/rotten tide/merge-blocker 
    opened by openshift-merge-robot 2
  • 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?

    lifecycle/frozen 
    opened by keithballdotnet 16
Owner
OpenShift
The developer and operations friendly Kubernetes distro
OpenShift
Hazelcast Storage for go-oauth2/oauth2

Hazelcast Storage for go-oauth2/oauth2

Clowre 0 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://

OpenShift 1.7k May 15, 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

Xenit AB 3 Dec 22, 2021
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

Richard Knop 1.9k May 17, 2022
Golang OAuth2.0 server

Golang OAuth2.0 server

BOKS 1 Feb 5, 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

Hemanth Krishna 8 Apr 25, 2022
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

Dalton Hubble 1.5k May 4, 2022
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

tarent 1.9k May 6, 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

Go 4.2k May 17, 2022
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

null 2 Apr 17, 2022
Identity-service - An OAuth2 identity provider that operates over gRPC

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

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

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

Otter Social 2 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

Loren Lisk 0 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

Saba Sahban 12 May 12, 2022
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

tigressma 1 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

Bartlomiej Mika 0 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

Geofrey Ernest 214 Feb 9, 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.

Cesanta Software 1.1k May 21, 2022
GLAuth 1.4k May 16, 2022