auth

package
v1.7.0 Latest Latest
Warning

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

Go to latest
Published: Jun 28, 2025 License: MIT Imports: 13 Imported by: 0

README

Authentication & Authorization

Overview

The Authentication & Authorization component provides a comprehensive solution for securing your services with JWT-based authentication and role-based authorization. It integrates with OpenID Connect (OIDC) providers and offers middleware for HTTP request authentication.

Features

  • JWT Token Management: Generate and validate JWT tokens
  • Role-Based Authorization: Control access based on user roles
  • OpenID Connect Integration: Authenticate users via OIDC providers
  • HTTP Middleware: Protect HTTP endpoints with authentication middleware
  • Context Utilities: Access user information from context

Installation

go get github.com/abitofhelp/servicelib/auth

Quick Start

See the Quick Start example for a complete, runnable example of how to use the auth component.

Configuration

See the Configuration example for a complete, runnable example of how to configure the auth component.

API Documentation

Core Types

The auth component provides several core types for authentication and authorization.

Auth

The main type that provides authentication and authorization functionality.

type Auth struct {
    // Fields
}
Config

Configuration for the Auth component.

type Config struct {
    // Fields
}
Key Methods

The auth component provides several key methods for authentication and authorization.

GenerateToken

Generates a JWT token for a user with specified roles, scopes, and resources.

func (a *Auth) GenerateToken(ctx context.Context, userID string, roles []string, scopes []string, resources []string) (string, error)
ValidateToken

Validates a JWT token and returns the claims.

func (a *Auth) ValidateToken(ctx context.Context, tokenString string) (*jwt.Claims, error)
IsAuthorized

Checks if the user in the context is authorized for a specific operation.

func (a *Auth) IsAuthorized(ctx context.Context, operation string) (bool, error)
HasRole

Checks if the user in the context has a specific role.

func (a *Auth) HasRole(ctx context.Context, role string) (bool, error)

Examples

For complete, runnable examples, see the following directories in the EXAMPLES directory:

Best Practices

  1. Use Middleware: Always use the auth middleware to protect your HTTP endpoints
  2. Check Authorization: Always check authorization before performing sensitive operations
  3. Validate Tokens: Always validate tokens before trusting their contents
  4. Use Context: Use context to pass user information between functions
  5. Handle Errors: Properly handle authentication and authorization errors

Troubleshooting

Common Issues
Token Validation Failures

If token validation fails, check that the token is not expired and that the signing key is correct.

Authorization Failures

If authorization checks fail, ensure that the user has the required roles and that the context contains the user information.

  • Errors - Error handling for authentication and authorization
  • Logging - Logging for authentication and authorization events
  • Middleware - HTTP middleware for authentication

Contributing

Contributions to this component are welcome! Please see the Contributing Guide for more information.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Overview

Package auth provides authentication and authorization functionality. It includes JWT token handling, OIDC integration, HTTP middleware, and role-based access control.

Package auth provides comprehensive authentication and authorization functionality for services.

This package implements a complete authentication and authorization system that includes:

  • JWT token generation and validation
  • OpenID Connect (OIDC) integration
  • HTTP middleware for securing API endpoints
  • Role-based access control (RBAC)
  • Context utilities for user information management

The auth package is designed to be flexible and configurable, supporting both local JWT-based authentication and integration with external identity providers through OIDC. It provides a unified interface for authentication and authorization operations, regardless of the underlying implementation.

Key components:

  • Auth: The main service that provides authentication and authorization functionality
  • Config: Configuration for JWT, OIDC, middleware, and authorization settings
  • Middleware: HTTP middleware for authenticating requests
  • JWT subpackage: Handles JWT token generation and validation
  • OIDC subpackage: Integrates with OpenID Connect providers
  • Service subpackage: Implements authorization logic

Example usage:

// Create an auth service
config := auth.DefaultConfig()
config.JWT.SecretKey = "your-secret-key"
config.JWT.Issuer = "your-service"

authService, err := auth.New(ctx, config, logger)
if err != nil {
    log.Fatalf("Failed to create auth service: %v", err)
}

// Use the middleware to protect routes
router := http.NewServeMux()
router.Handle("/api/", authService.Middleware()(apiHandler))

// Generate a token for a user
token, err := authService.GenerateToken(ctx, "user123", []string{"admin"}, []string{"read:users"}, []string{})
if err != nil {
    log.Fatalf("Failed to generate token: %v", err)
}

// Check if a user is authorized for an operation
authorized, err := authService.IsAuthorized(ctx, "read:users")
if err != nil {
    log.Fatalf("Failed to check authorization: %v", err)
}

// Get user information from context
userID, err := authService.GetUserID(ctx)
if err != nil {
    log.Fatalf("Failed to get user ID: %v", err)
}

The auth package is designed to be used as a dependency by other packages in the application, providing a consistent authentication and authorization interface throughout the codebase.

Package auth provides authentication and authorization functionality. This file contains compatibility functions for the old auth/errors package.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidToken is returned when a token is invalid
	ErrInvalidToken = errors.NewAuthenticationError("invalid token", "", nil)

	// ErrExpiredToken is returned when a token has expired
	ErrExpiredToken = errors.NewAuthenticationError("token expired", "", nil)

	// ErrMissingToken is returned when a token is missing
	ErrMissingToken = errors.NewAuthenticationError("token missing", "", nil)

	// ErrInvalidSignature is returned when a token has an invalid signature
	ErrInvalidSignature = errors.NewAuthenticationError("invalid token signature", "", nil)

	// ErrInvalidClaims is returned when a token has invalid claims
	ErrInvalidClaims = errors.NewAuthenticationError("invalid token claims", "", nil)

	// ErrUnauthorized is returned when a user is not authorized to perform an operation
	ErrUnauthorized = errors.ErrUnauthorized

	// ErrForbidden is returned when a user is forbidden from performing an operation
	ErrForbidden = errors.ErrForbidden

	// ErrInvalidConfig is returned when the configuration is invalid
	ErrInvalidConfig = errors.NewConfigurationError("invalid configuration", "", "", nil)

	// ErrInternal is returned when an internal error occurs
	ErrInternal = errors.ErrInternal

	// ErrNotImplemented is returned when a feature is not implemented
	ErrNotImplemented = errors.New(errors.InternalErrorCode, "not implemented")
)

Error constants for backward compatibility

Functions

func GetContext added in v1.4.0

func GetContext(err error, key string) (interface{}, bool)

GetContext gets a context value from an error for backward compatibility

func GetMessage added in v1.4.0

func GetMessage(err error) (string, bool)

GetMessage gets the message from an error for backward compatibility

func GetOp added in v1.4.0

func GetOp(err error) (string, bool)

GetOp gets the operation from an error for backward compatibility

func GetUserIDFromContext

func GetUserIDFromContext(ctx context.Context) (string, bool)

GetUserIDFromContext retrieves the user ID from the context. This function extracts the user ID that was previously set in the context by either the authentication middleware or the WithUserID function.

Parameters:

  • ctx: The context from which to retrieve the user ID.

Returns:

  • string: The user ID if found in the context.
  • bool: true if the user ID was found in the context, false otherwise.

func GetUserRolesFromContext

func GetUserRolesFromContext(ctx context.Context) ([]string, bool)

GetUserRolesFromContext retrieves the user roles from the context. This function extracts the user roles that were previously set in the context by either the authentication middleware or the WithUserRoles function.

Parameters:

  • ctx: The context from which to retrieve the user roles.

Returns:

  • []string: A slice of role strings if found in the context.
  • bool: true if the user roles were found in the context, false otherwise.

func IsAuthenticated

func IsAuthenticated(ctx context.Context) bool

IsAuthenticated checks if the user is authenticated. This function determines if the context contains authentication information, specifically a user ID. It's a convenience function for checking if a request has gone through the authentication process successfully.

Parameters:

  • ctx: The context to check for authentication information.

Returns:

  • bool: true if the user is authenticated (has a user ID in the context), false otherwise.

func ValidateConfig

func ValidateConfig(config Config) *validation.ValidationResult

ValidateConfig validates the configuration for the auth module. It checks that all required fields are set and have valid values, including:

  • JWT secret key and issuer
  • JWT token duration (must be positive)
  • Remote validation URL and timeout if remote validation is enabled
  • OIDC issuer URL and client ID if OIDC is configured
  • Admin role name and read-only role name
  • Read operation prefixes (must not be empty)

Parameters:

  • config: The configuration to validate.

Returns:

  • *validation.ValidationResult: A validation result containing any validation errors. If the result's IsValid() method returns true, the configuration is valid.

func WithContext added in v1.4.0

func WithContext(err error, key string, value interface{}) error

WithContext adds context to an error for backward compatibility

func WithMessage added in v1.4.0

func WithMessage(err error, message string) error

WithMessage adds a message to an error for backward compatibility

func WithOp added in v1.4.0

func WithOp(err error, op string) error

WithOp adds an operation to an error for backward compatibility

func WithUserID

func WithUserID(ctx context.Context, userID string) context.Context

WithUserID returns a new context with the user ID. This function adds the user ID to the context, which can be later retrieved using GetUserIDFromContext. It's typically used in testing or when manually setting up an authenticated context without going through the normal authentication flow.

Parameters:

  • ctx: The parent context to which the user ID will be added.
  • userID: The user ID to add to the context.

Returns:

  • context.Context: A new context containing the user ID.

func WithUserRoles

func WithUserRoles(ctx context.Context, roles []string) context.Context

WithUserRoles returns a new context with the user roles. This function adds the user roles to the context, which can be later retrieved using GetUserRolesFromContext. It's typically used in testing or when manually setting up an authenticated context without going through the normal authentication flow.

Parameters:

  • ctx: The parent context to which the user roles will be added.
  • roles: A slice of role strings to add to the context.

Returns:

  • context.Context: A new context containing the user roles.

func Wrap added in v1.4.0

func Wrap(err error, message string) error

Wrap wraps an error with a message for backward compatibility

Types

type Auth

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

Auth provides authentication and authorization functionality. It encapsulates JWT token handling, OIDC integration, HTTP middleware, and role-based access control in a unified interface. The Auth struct is the main entry point for all authentication and authorization operations.

func New

func New(ctx context.Context, config Config, logger *zap.Logger) (*Auth, error)

New creates a new Auth instance with the provided configuration and logger. It initializes the JWT service, OIDC service (if configured), authentication middleware, and authorization service based on the provided configuration. The function validates the configuration before creating any services and returns an error if the configuration is invalid.

Parameters:

  • ctx: The context for the operation, which can be used for tracing and cancellation.
  • config: The configuration for the auth module.
  • logger: The logger to use for logging operations and errors. If nil, a no-op logger will be used.

Returns:

  • *Auth: A new Auth instance if successful.
  • error: An error if the configuration is invalid or if any service initialization fails.

func (*Auth) GenerateToken

func (a *Auth) GenerateToken(ctx context.Context, userID string, roles []string, scopes []string, resources []string) (string, error)

GenerateToken generates a new JWT token for a user with the specified roles, scopes, and resources. The token includes claims for the user ID, roles, scopes, and resources, and is signed with the configured secret key. The token has an expiration time based on the configured token duration.

Parameters:

  • ctx: The context for the operation, which can be used for tracing and cancellation.
  • userID: The unique identifier of the user for whom the token is being generated.
  • roles: The roles assigned to the user (e.g., "admin", "user").
  • scopes: The OAuth2 scopes granted to the user (e.g., "read:users", "write:users").
  • resources: The resources the user has access to.

Returns:

  • string: The generated JWT token as a string.
  • error: An error if token generation fails.

func (*Auth) GetUserID

func (a *Auth) GetUserID(ctx context.Context) (string, error)

GetUserID retrieves the user ID from the context. This method extracts the user ID that was previously set in the context by the authentication middleware. It's a convenience method for accessing the authenticated user's identity.

Parameters:

  • ctx: The context for the operation, which must contain user information. This is typically set by the authentication middleware.

Returns:

  • string: The user ID if found in the context.
  • error: An error if the user ID cannot be retrieved, such as if the context does not contain user information or if the user is not authenticated.

func (*Auth) GetUserRoles

func (a *Auth) GetUserRoles(ctx context.Context) ([]string, error)

GetUserRoles retrieves the user roles from the context. This method extracts the user roles that were previously set in the context by the authentication middleware. It's a convenience method for accessing the authenticated user's roles for authorization purposes.

Parameters:

  • ctx: The context for the operation, which must contain user information. This is typically set by the authentication middleware.

Returns:

  • []string: A slice of role strings if found in the context.
  • error: An error if the user roles cannot be retrieved, such as if the context does not contain user information or if the user is not authenticated.

func (*Auth) HasRole

func (a *Auth) HasRole(ctx context.Context, role string) (bool, error)

HasRole checks if the user has a specific role. It retrieves the user's roles from the context and checks if the specified role is included in the user's roles. This method is case-sensitive.

Parameters:

  • ctx: The context for the operation, which must contain user information. This is typically set by the authentication middleware.
  • role: The role to check for, such as "admin" or "user".

Returns:

  • bool: true if the user has the specified role, false otherwise.
  • error: An error if the role check fails, such as if the context does not contain user information.

func (*Auth) IsAdmin

func (a *Auth) IsAdmin(ctx context.Context) (bool, error)

IsAdmin checks if the user has the admin role. This is a convenience method that checks if the user has the role configured as the admin role in the service configuration.

Parameters:

  • ctx: The context for the operation, which must contain user information. This is typically set by the authentication middleware.

Returns:

  • bool: true if the user has the admin role, false otherwise.
  • error: An error if the role check fails, such as if the context does not contain user information.

func (*Auth) IsAuthorized

func (a *Auth) IsAuthorized(ctx context.Context, operation string) (bool, error)

IsAuthorized checks if the user is authorized to perform the operation. It uses the user's roles and the operation name to determine if the user is authorized. Users with the admin role are authorized for all operations. Users with the read-only role are authorized only for read operations.

Parameters:

  • ctx: The context for the operation, which must contain user information. This is typically set by the authentication middleware.
  • operation: The name of the operation to check authorization for. This should be a string that identifies the operation, such as "read:users".

Returns:

  • bool: true if the user is authorized, false otherwise.
  • error: An error if the authorization check fails, such as if the context does not contain user information.

func (*Auth) Middleware

func (a *Auth) Middleware() func(http.Handler) http.Handler

Middleware returns the HTTP middleware for authentication. This middleware intercepts HTTP requests, extracts and validates authentication tokens, and adds user information to the request context. It can be configured to skip authentication for specific paths and to require authentication for all other paths.

Returns:

  • func(http.Handler) http.Handler: A middleware function that can be used with standard HTTP handlers or routers to add authentication to routes.

func (*Auth) ValidateToken

func (a *Auth) ValidateToken(ctx context.Context, tokenString string) (*jwt.Claims, error)

ValidateToken validates a JWT token and returns the claims if valid. It verifies the token signature, checks the expiration time, and validates the issuer. If remote validation is configured, it also validates the token with the remote validation service.

Parameters:

  • ctx: The context for the operation, which can be used for tracing and cancellation.
  • tokenString: The JWT token string to validate.

Returns:

  • *jwt.Claims: The claims from the token if validation is successful.
  • error: An error if token validation fails, such as if the token is expired, has an invalid signature, or fails remote validation.

type Config

type Config struct {
	// JWT configuration
	JWT struct {
		// SecretKey is the key used to sign and verify JWT tokens
		SecretKey string

		// TokenDuration is the validity period for generated tokens
		TokenDuration time.Duration

		// Issuer identifies the entity that issued the token
		Issuer string

		// Remote validation configuration
		Remote struct {
			// Enabled determines if remote validation should be used
			Enabled bool

			// ValidationURL is the URL of the remote validation endpoint
			ValidationURL string

			// ClientID is the client ID for the remote validation service
			ClientID string

			// ClientSecret is the client secret for the remote validation service
			ClientSecret string

			// Timeout is the timeout for remote validation operations
			Timeout time.Duration
		}
	}

	// OIDC configuration
	OIDC struct {
		// IssuerURL is the URL of the OIDC provider
		IssuerURL string

		// ClientID is the client ID for the OIDC provider
		ClientID string

		// ClientSecret is the client secret for the OIDC provider
		ClientSecret string

		// RedirectURL is the redirect URL for the OIDC provider
		RedirectURL string

		// Scopes are the OAuth2 scopes to request
		Scopes []string

		// Timeout is the timeout for OIDC operations
		Timeout time.Duration
	}

	// Middleware configuration
	Middleware struct {
		// SkipPaths are paths that should skip authentication
		SkipPaths []string

		// RequireAuth determines if authentication is required for all requests
		RequireAuth bool
	}

	// Service configuration
	Service struct {
		// AdminRoleName is the name of the admin role
		AdminRoleName string

		// ReadOnlyRoleName is the name of the read-only role
		ReadOnlyRoleName string

		// ReadOperationPrefixes are prefixes for read-only operations
		ReadOperationPrefixes []string
	}
}

Config holds the configuration for the auth module. It contains settings for JWT token handling, OIDC integration, HTTP middleware, and authorization service behavior.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the default configuration for the auth module. It sets reasonable default values for all configuration options, including:

  • JWT token duration (24 hours)
  • JWT issuer ("auth")
  • Remote validation timeout (10 seconds)
  • OIDC timeout (10 seconds)
  • OIDC scopes (openid, profile, email)
  • Admin role name ("admin")
  • Read-only role name ("authuser")
  • Read operation prefixes for authorization

Returns:

  • Config: A configuration struct with default values.

Directories

Path Synopsis
Package config provides adapters for auth configuration.
Package config provides adapters for auth configuration.
Package errors provides comprehensive error handling for the auth module.
Package errors provides comprehensive error handling for the auth module.
Package jwt provides JWT token handling for the auth module.
Package jwt provides JWT token handling for the auth module.
Package middleware provides HTTP middleware for authentication.
Package middleware provides HTTP middleware for authentication.
Package oidc provides OpenID Connect integration for the auth module.
Package oidc provides OpenID Connect integration for the auth module.
Package service provides authorization services for the auth module.
Package service provides authorization services for the auth module.

Jump to

Keyboard shortcuts

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