oauth2

package module
v0.13.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 29, 2023 License: Apache-2.0 Imports: 15 Imported by: 7

README

oauth2go

build Go Report Card codecov

What is this?

oauth2go aims to be a basic OAuth 2.0 authorization server that implements at least some of the most basic OAuth 2.0 flows. Since the canonical import name for this package is oauth2, it also provides type aliases for exported structs and interfaces of the golang.org/x/oauth2 package, so that both OAuth 2.0 client and server structs can be accessed using an oauth2 package. Additional structs for specialized client flows or endpoints still need to be retrieved from the corresponding sub-package, such as golang.org/x/oauth2/clientcredentials.

In it's bare form, this package only contains an authorization server, which does not have any "users" or any possibility to "log in", as this is the duty of an authentication server. However, for convenience, the login package includes a very basic authentication server which implements a POST form based /login endpoint and a simple login form located in login/login.html.

Why?

This project mainly started out of the need to have a very small, embedded OAuth 2.0 authorization server, written in Go. The main use case was a "demo" or all-in-one-mode of a large micro-service application, as well as integration testing. In production deployments, this application uses a dedicated authentication server, but I wanted something for my "demo" mode. While there are some implementations out there, it was not easy to fulfill my requirements.

I wanted something small, lean and easily embedded in my Go code, not a full-blown authentication services with thousands of adapters and backends (written in Java).

I wanted something that intentionally does not support legacy flows but focuses on the newer RFCs and possibly move into the direction of OAuth 2.1.

I wanted something with zero (or almost) zero dependencies. Therefore I strictly try to only include the following dependencies: golang.org/x/oauth2, golang.org/x/crypto (which hopefully might be part of the standard library one day) and github.com/golang-jwt/jwt (which itself also has a zero dependency policy)

How to use?

A very simple OAuth 2.0 authorization server with an integrated authentication ("login") server can be created like this.

import (
    oauth2 "github.com/oxisto/oauth2go"
    "github.com/oxisto/oauth2go/login"
)

func main() {
    var srv *oauth2.AuthorizationServer

    srv = oauth2.NewServer(":8000",
        login.WithLoginPage(login.WithUser("admin", "admin")),
    )

    srv.ListenAndServe()
}

If you want to use this project as a small standalone authentication server, you can use the Docker image to spawn one. The created user and client credentials will be printed on the console.

docker run -p 8000:8000 ghcr.io/oxisto/oauth2go

A login form is available on http://localhost:8000/login.

(To be) Implemented Standards

  • RFC 6749. The OAuth 2.0 Authorization Framework
  • RFC 6750. The OAuth 2.0 Authorization Framework: Bearer Token Usage
  • RFC 7517. JSON Web Key (JWK)
  • RFC 7636. Proof Key for Code Exchange by OAuth Public Clients
  • RFC 8414. OAuth 2.0 Authorization Server Metadata

Documentation

Index

Examples

Constants

View Source
const (
	ErrorInvalidRequest = "invalid_request"
	ErrorInvalidClient  = "invalid_client"
	ErrorInvalidGrant   = "invalid_grant"

	DefaultExpireIn = time.Hour * 24
	DefaultAddress  = "http://localhost:8000"
)

Variables

View Source
var (
	ErrClientNotFound             = errors.New("client not found")
	ErrInvalidBasicAuthentication = errors.New("invalid or missing basic authentication")
)
View Source
var ReuseTokenSource = oauth2.ReuseTokenSource

ReuseTokenSource is a function alias for https://pkg.go.dev/golang.org/x/oauth2#ReuseTokenSource.

View Source
var SetAuthURLParam = oauth2.SetAuthURLParam

SetAuthURLParam is a function alias for https://pkg.go.dev/golang.org/x/oauth2#SetAuthURLParam.

View Source
var StaticTokenSource = oauth2.StaticTokenSource

StaticTokenSource is a function alias for https://pkg.go.dev/golang.org/x/oauth2#StaticTokenSource.

Functions

func Error added in v0.2.0

func Error(w http.ResponseWriter, error string, statusCode int)

func GenerateCodeChallenge added in v0.5.3

func GenerateCodeChallenge(verifier string) string

func GenerateSecret added in v0.5.0

func GenerateSecret() string

func RedirectError added in v0.5.0

func RedirectError(w http.ResponseWriter,
	r *http.Request,
	redirectURI string,
	error string,
	errorDescription string,
)

Types

type AuthCodeOption added in v0.3.0

type AuthCodeOption = oauth2.AuthCodeOption

AuthCodeOption is a type alias for https://pkg.go.dev/golang.org/x/oauth2#AuthCodeOption.

type AuthStyle added in v0.2.0

type AuthStyle = oauth2.AuthStyle

AuthStyle is a type alias for https://pkg.go.dev/golang.org/x/oauth2#AuthStyle.

type AuthorizationServer added in v0.2.0

type AuthorizationServer struct {
	http.Server
	// contains filtered or unexported fields
}

AuthorizationServer is an OAuth 2.0 authorization server

Example

ExampleLoginPage sets up an OAuth 2.0 authorization server with an integrated login page (acting as an authentication server).

package main

import (
	"fmt"

	oauth2 "github.com/oxisto/oauth2go"
	"github.com/oxisto/oauth2go/login"
)

func main() {
	var srv *oauth2.AuthorizationServer
	var port = 8000

	srv = oauth2.NewServer(fmt.Sprintf(":%d", port),
		login.WithLoginPage(login.WithUser("admin", "admin")),
	)

	fmt.Printf("Creating new OAuth 2.0 server on %d", port)

	go srv.ListenAndServe()
	defer srv.Close()
}
Output:

Creating new OAuth 2.0 server on 8000

func NewServer

func NewServer(addr string, opts ...AuthorizationServerOption) *AuthorizationServer

func (*AuthorizationServer) GenerateToken added in v0.5.4

func (srv *AuthorizationServer) GenerateToken(clientID string, signingKeyID int, refreshKeyID int) (token *Token, err error)

GenerateToken generates a Token (comprising at least an acesss token) for a specific client, as specified by its ID. A signingKey needs to be specified, otherwise an error is thrown. Optionally, if a refreshKey is specified, that key is used to also create a refresh token.

func (*AuthorizationServer) GetClient added in v0.5.0

func (srv *AuthorizationServer) GetClient(clientID string) (*Client, error)

GetClient returns the client for the given ID or ErrClientNotFound.

func (*AuthorizationServer) IssueCode added in v0.5.0

func (srv *AuthorizationServer) IssueCode(challenge string) (code string)

IssueCode implements CodeIssuer.

func (*AuthorizationServer) PublicKeys added in v0.5.0

func (srv *AuthorizationServer) PublicKeys() map[int]*ecdsa.PublicKey

PublicKey returns the public keys of the signing key of this authorization server in a map, indexed by its kid.

func (*AuthorizationServer) ValidateCode added in v0.5.0

func (srv *AuthorizationServer) ValidateCode(verifier string, code string) bool

ValidateCode implements CodeIssuer. It checks if the code exists and is not expired. If the code exists, it will be invalidated after this call.

type AuthorizationServerOption added in v0.2.0

type AuthorizationServerOption func(srv *AuthorizationServer)

func WithAllowedOrigins added in v0.5.13

func WithAllowedOrigins(origin string) AuthorizationServerOption

func WithClient

func WithClient(
	clientID string,
	clientSecret string,
	redirectURI string,
) AuthorizationServerOption

func WithPublicURL added in v0.7.0

func WithPublicURL(publicURL string) AuthorizationServerOption

func WithSigningKeysFunc added in v0.5.5

func WithSigningKeysFunc(f signingKeysFunc) AuthorizationServerOption

type Client added in v0.2.0

type Client struct {
	ClientID string

	ClientSecret string

	RedirectURI string
}

func (*Client) Public added in v0.5.1

func (c *Client) Public() bool

Public returns true if this client is a public client. We enforce certain additional security measures for public clients, for example PKCE.

type CodeIssuer added in v0.5.0

type CodeIssuer interface {
	IssueCode(challenge string) string
	ValidateCode(verifier string, code string) bool
}

type Config added in v0.2.0

type Config = oauth2.Config

Config is a type alias for https://pkg.go.dev/golang.org/x/oauth2#Config.

type Endpoint added in v0.2.0

type Endpoint = oauth2.Endpoint

Endpoint is a type alias for https://pkg.go.dev/golang.org/x/oauth2#Endpoint.

type JSONWebKey

type JSONWebKey struct {
	Kid string `json:"kid"`

	Kty string `json:"kty"`

	Crv string `json:"crv"`

	X string `json:"x"`

	Y string `json:"y"`
}

JSONWebKey is a JSON Web Key that only supports elliptic curve keys for now.

type JSONWebKeySet added in v0.3.0

type JSONWebKeySet struct {
	Keys []JSONWebKey `json:"keys"`
}

JSONWebKeySet is a JSON Web Key Set.

type Logger added in v0.2.0

type Logger interface {
	Printf(format string, v ...interface{})
}

type RetrieveError added in v0.3.0

type RetrieveError = oauth2.RetrieveError

RetrieveError is a type alias for https://pkg.go.dev/golang.org/x/oauth2#RetrieveError.

type ServerMetadata added in v0.7.0

type ServerMetadata struct {
	Issuer                 string   `json:"issuer"`
	AuthorizationEndpoint  string   `json:"authorization_endpoint"`
	TokenEndpoint          string   `json:"token_endpoint"`
	JWKSURI                string   `json:"jwks_uri"`
	SupportedScopes        []string `json:"scopes_supported"`
	SupportedResponseTypes []string `json:"response_types_supported"`
	SupportedGrantTypes    []string `json:"grant_types_supported"`
}

ServerMetadata is a struct that contains metadata according to RFC 8414.

See https://datatracker.ietf.org/doc/rfc8414/.

type Token added in v0.3.0

type Token = oauth2.Token

Token is a type alias for https://pkg.go.dev/golang.org/x/oauth2#Token.

type TokenSource added in v0.3.0

type TokenSource = oauth2.TokenSource

TokenSource is a type alias for https://pkg.go.dev/golang.org/x/oauth2#TokenSource.

type Transport added in v0.3.0

type Transport = oauth2.Transport

Transport is a type alias for https://pkg.go.dev/golang.org/x/oauth2#Transport.

Directories

Path Synopsis
cmd
internal
mock
package mock contains several structs that are used in various unit tests
package mock contains several structs that are used in various unit tests
package login contains an optional "login" (authentication) server that can be used.
package login contains an optional "login" (authentication) server that can be used.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL