fiberoidc

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jan 12, 2025 License: MIT Imports: 9 Imported by: 0

README

Fiber OIDC

Fiber OIDC Middleware.
Yes, it's quite a lot chunkier than fiber, but it does provide an easy way to integrate OIDC into your app.

N.B. It does things like use open plaintext cookies, and doesn't have a full set of hooks for all occasions. That said, these things are easy to fix with a PR that enables support for your use case.

Quickstart

To install: go get github.com/kncept/fiber-oidc

Example snippet from another app:

	fiberOidc, err := fiberoidc.New(ctx, &fiberoidc.Config{
		Issuer:         "https://accounts.google.com",
		ClientId:       os.Getenv("OIDC_CLIENT_ID"),
		ClientSecret:   os.Getenv("OIDC_CLIENT_SECRET"),
		RedirectUri:    "http://localhost:3000/oauth2/callback",
		AuthCookieName: "bearer-auth",
	})
	if err != nil {
		return nil, err
	}

	app.Get(fiberOidc.CallbackPath(), fiberOidc.CallbackHandler())
	app.Get("/", fiberOidc.UnprotectedRoute(), func(c *fiber.Ctx) error {
		subject := "no auth present"
		idToken := fiberoidc.IdTokenFromContext(c)
		if idToken != nil {
			subject = idToken.Subject
		}
		return c.Render("index", subject)
	})
	app.Get("/me", fiberOidc.ProtectedRoute(), func(c *fiber.Ctx) error {
		idToken := fiberoidc.IdTokenFromContext(c)
		return c.Render("index", idToken.Subject)
	})

You can access the id token in your handler by doing this: idToken := fiberoidc.IdTokenFromContext(c)

OIDC Library Implementation

This middleware is built over https://github.com/coreos/go-oidc, which provides support for the https://pkg.go.dev/golang.org/x/oauth2 package.

Handling extra claims

Use a struct something like this:

type OidcClaims struct {
   Subject  string `json:"sub"`
   Issuer   string `json:"iss"`
   Audience string `json:"aud"`

   Name string `json:"name,omitempty"`

   Email         string `json:"email,omitempty"`
   EmailVerified bool   `json:"email_verified,omitempty"`

   PoneNumber          string `json:"phone_number,omitempty"`
   PhoneNumberVerified bool   `json:"phone_number_verified,omitempty"`
}

with the following code snippet in your handler:

	idToken := fiberoidc.IdTokenFromContext(c)
    claims := &OidcClaims{}
    err = idToken.Claims(&claims)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IdTokenFromContext

func IdTokenFromContext(c *fiber.Ctx) *gooidc.IDToken

IdTokenFromContext returns the jwt token found in the context returns a nil pointer if nothing exists

Types

type Config

type Config struct {
	Issuer       string
	ClientId     string
	ClientSecret string

	// OPTIONAL, will be defaulted if unspecified
	Scopes []string

	// FULLY QUALIFIED Oauth2 Callback path
	RedirectUri string

	// OPTIONAL
	// trigger oidc callback on this path.
	// It MUST match the RedirectUri value
	// If blank, this is default to the entire path from the RedirectUri
	CallbackPath string

	// OPTIONAL
	//
	// if set, also use an auth cookie (allow identity token to be set directly)
	AuthCookieName string

	// OPTIONAL
	//
	// Unauthorized defines the response body for unauthorized responses.
	// By default it will return with a 401 Unauthorized and the correct WWW-Auth header
	Unauthorized fiber.Handler

	// OPTIONAL
	//
	// Called to serialize state for the OIDC redirect
	// If unspecified, will just the be the current path
	//
	// Should be paired with a SuccessHandler if provided
	LoginStateEncoder func(c *fiber.Ctx) (string, error)
	// Optional
	//
	// Called on login success to restore any application state there
	// may have been.
	// if unspecified, will assume that 'state' was the url path, and redirect there
	//
	// Should be paired with a StateEncoder if provided
	LoginSuccessHandler func(state string, c *fiber.Ctx) error
}

Config defines the config for middleware.

func (*Config) Validate

func (obj *Config) Validate() error

func (*Config) WithDefaults

func (cfg *Config) WithDefaults() *Config

Helper function to set default values

type FiberOidc

type FiberOidc interface {
	// Allows protection of the entire app in one handler
	// This style matches the way that many web applications (eg: spring boot)
	// tend to handle security
	ProtectedApp(routeProtector RouteProtectorFunc) fiber.Handler

	// Allows protection of a single route
	// Will redirect if required
	ProtectedRoute() fiber.Handler

	// Does not protect the route, but will still bind any valid
	// auth token to the request
	UnprotectedRoute() fiber.Handler

	// Handles the OIDC callback
	CallbackHandler() fiber.Handler
	// easy access to the callback path
	CallbackPath() string
}

func New

func New(ctx context.Context, config *Config) (FiberOidc, error)

type FiberOidcStruct

type FiberOidcStruct struct {
	Config          *Config
	OidcConfig      *oauth2.Config
	OidcProvider    *gooidc.Provider
	IdTokenVerifier *gooidc.IDTokenVerifier
}

direct access to fields, if you need to tweak or override something which should, of course, be entirely unnessesary

func (*FiberOidcStruct) CallbackHandler

func (obj *FiberOidcStruct) CallbackHandler() fiber.Handler

func (*FiberOidcStruct) CallbackPath

func (obj *FiberOidcStruct) CallbackPath() string

func (*FiberOidcStruct) ProtectedApp

func (obj *FiberOidcStruct) ProtectedApp(routeProtector RouteProtectorFunc) fiber.Handler

New creates a new middleware handler

func (*FiberOidcStruct) ProtectedRoute

func (obj *FiberOidcStruct) ProtectedRoute() fiber.Handler

func (*FiberOidcStruct) UnprotectedRoute

func (obj *FiberOidcStruct) UnprotectedRoute() fiber.Handler

type RouteProtectorFunc

type RouteProtectorFunc func(c *fiber.Ctx) (bool, error)

Defines a function to skip this middleware when returning false. Use this to determine Authenticated and Non-Authenticated routes

Jump to

Keyboard shortcuts

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