oidcagent

package
v0.0.0-...-f9f7919 Latest Latest
Warning

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

Go to latest
Published: Jul 23, 2024 License: Apache-2.0, Apache-2.0 Imports: 21 Imported by: 0

README

go-oidc-agent

Warning This repo is no longer maintained. It's now a package within Nexodus

Release License Build Coverage Go Report Card

go-oidc-agent is a small binary designed to act as a Backend-For-Frontend, handling the OIDC authentication on behalf of the frontend app.

It is heavily influenced by oauth-agent-node-express with the following notable differences:

  1. It's written in Go
  2. The session storage (used for tokens) is swappable so it can use encrypted cookies, memcached etc...
  3. It acts as a proxy for request from the frontend the configured backend API, adding the necessary authentication credentials.

There are also some omissions, which will need addressing before this can be used in production.

  1. CSRF Token Support

Design

design

Example

There is a working example in the examples directory. To use this you must first add 3 domains to your /etc/hosts.

  • auth.widgetcorp.local - The Auth Server
  • widgets.local - Your Frontend
  • api.widgets.local - Backend For Frontend

To start the example, run docker compose up -d.

Note Podman Compatibility This will work on podman-compose also, but you will need to.

[containers]
base_hosts_file="none

You can then browse to http://widgets.local:8080, which will redirect you to the login page.

The login page will call the backend to find the login URL, and then redirect you to http://auth.widgetcorp.local where you can login with admin@widgetcorp.com and the password admin.

On successful login, you're redirected back to the frontend. The frontend sends the received code to the backend where it's exchanged for a token that can be used to access the API. This token is stored in an encrypted cookie.

Once you're fully authenticated, the frontend may then call the /api enpdoint of the backend. This proxies requests to the apiserver with the credentials from the securecookie injected.

Documentation

Index

Constants

View Source
const (
	TokenKey   = "token"
	IDTokenKey = "id_token"
)

Variables

This section is empty.

Functions

func AddCodeFlowRoutes

func AddCodeFlowRoutes(r gin.IRouter, auth *OidcAgent)

func AddDeviceFlowRoutes

func AddDeviceFlowRoutes(r gin.IRouter, auth *OidcAgent)

func JsonStringToToken

func JsonStringToToken(s string) (*oauth2.Token, error)

func NewCodeFlowRouter

func NewCodeFlowRouter(auth *OidcAgent) *gin.Engine

func NewDeviceFlowRouter

func NewDeviceFlowRouter(auth *OidcAgent) *gin.Engine

Types

type IDTokenVerifier

type IDTokenVerifier interface {
	Verify(ctx context.Context, rawIDToken string) (*oidc.IDToken, error)
}

type OauthConfig

type OauthConfig interface {
	AuthCodeURL(state string, opts ...oauth2.AuthCodeOption) string
	Exchange(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error)
	TokenSource(ctx context.Context, t *oauth2.Token) oauth2.TokenSource
}

type OidcAgent

type OidcAgent struct {
	// contains filtered or unexported fields
}

func NewOidcAgent

func NewOidcAgent(ctx context.Context,
	logger *zap.Logger,
	oidcProvider string,
	oidcBackchannel string,
	insecureTLS bool,
	clientID string,
	clientSecret string,
	redirectURL string,
	scopes []string,
	domain string,
	origins []string,
	backend string,
	cookieKey string,
) (*OidcAgent, error)

func (*OidcAgent) CheckAuth

func (o *OidcAgent) CheckAuth(c *gin.Context)

CheckAuth checks if the user is authenticated. @Summary Check Authentication @Description Checks if the user is currently authenticated @Id CheckAuth @Tags Auth @Accept json @Produce json @Success 200 {object} map[string]bool "logged_in status will be returned" @Router /check/auth [get]

func (*OidcAgent) Claims

func (o *OidcAgent) Claims(c *gin.Context)

Claims fetches the claims associated with the user's access token. @Summary Get Access Token Claims @Description Retrieves the claims present in the user's access token. @Id Claims @Tags Auth @Accept json @Produce json @Success 200 {object} map[string]interface{} @Router /web/claims [get]

func (*OidcAgent) CodeFlowProxy

func (o *OidcAgent) CodeFlowProxy(c *gin.Context)

func (*OidcAgent) CookieSessionMiddleware

func (auth *OidcAgent) CookieSessionMiddleware() gin.HandlerFunc

func (*OidcAgent) CorsMiddleware

func (auth *OidcAgent) CorsMiddleware() gin.HandlerFunc

func (*OidcAgent) DeviceFlowProxy

func (o *OidcAgent) DeviceFlowProxy(c *gin.Context)

func (*OidcAgent) DeviceStart

func (o *OidcAgent) DeviceStart(c *gin.Context)

DeviceStart initiates the device login process. @Summary Start Login @Description Starts a device login request @Id DeviceStart @Tags Auth @Accept json @Produce json @Success 200 {object} models.DeviceStartResponse @Router /device/login/start [post]

func (*OidcAgent) LoginEnd

func (o *OidcAgent) LoginEnd(c *gin.Context)

LoginEnd completes the OIDC login process. @Summary Completes OIDC Web Login @Description Handles the callback from the OAuth2/OpenID provider and verifies the tokens. @Id WebEnd @Tags Auth @Accepts json @Produce json @Param code query string true "oauth2 code from authorization server" @Param state query string true "state value from the login start request" @Param error query string true "error message if login failed" @Success 302 {string} string "Redirects to the URLs specified in the login start request" @Router /web/login/end [get]

func (*OidcAgent) LoginStart

func (o *OidcAgent) LoginStart(c *gin.Context)

LoginStart initiates the OIDC login process. @Summary Initiates OIDC Web Login @Description Generates state and nonce, then redirects the user to the OAuth2 authorization URL. @Id WebStart @Tags Auth @Accepts json @Produce json @Param redirect query string true "URL to redirect to if login succeeds" @Param failure query string false "URL to redirect to if login fails (optional)" @Success 302 {string} string "Redirects to the OAuth2 authorization URL" @Router /web/login/start [get]

func (*OidcAgent) Logout

func (o *OidcAgent) Logout(c *gin.Context)

Logout provides the URL to log out the current user. @Summary Generate Logout URL @Description Provides the URL to initiate the logout process for the current user. @Id Logout @Tags Auth @Accept json @Produce json @Param redirect query string true "URL to redirect to after logout" @Success 302 {string} string "Redirects to the OAuth2 logout URL" @Router /web/logout [get]

func (*OidcAgent) LogoutURL

func (o *OidcAgent) LogoutURL(idToken string, redirect string) (*url.URL, error)

func (*OidcAgent) OriginVerifier

func (a *OidcAgent) OriginVerifier() gin.HandlerFunc

func (*OidcAgent) Refresh

func (o *OidcAgent) Refresh(c *gin.Context)

Refresh updates the user's access token. @Summary Refresh Access Token @Description Obtains and updates a new access token for the user. @Id Refresh @Tags Auth @Accept json @Produce json @Success 204 @Router /web/refresh [post]

func (*OidcAgent) UserInfo

func (o *OidcAgent) UserInfo(c *gin.Context)

UserInfo retrieves details about the currently authenticated user. @Summary Retrieve Current User Information @Description Fetches and returns information for the user who is currently authenticated. @Id UserInfo @Tags Auth @Accept json @Produce json @Success 200 {object} models.UserInfoResponse @Router /web/user_info [get]

type OpenIDConnectProvider

type OpenIDConnectProvider interface {
	Endpoint() oauth2.Endpoint
	UserInfo(ctx context.Context, tokenSource oauth2.TokenSource) (*oidc.UserInfo, error)
}

Directories

Path Synopsis
cmd
examples

Jump to

Keyboard shortcuts

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