Skip to content

Latest commit

 

History

History
141 lines (115 loc) · 4.53 KB

File metadata and controls

141 lines (115 loc) · 4.53 KB

security

Tier: Platform · Status: Full · Java original: Spring Security · .NET project: Microsoft.AspNetCore.Authentication.JwtBearer

Overview

security is the framework's HTTP-layer authentication and authorization tier:

  • Verifier — port for token validators (any IDP adapter satisfies it).
  • BearerMiddleware — extracts Authorization: Bearer <token>, calls the Verifier, stores the resulting Authentication on the request context.
  • FilterChain — path-pattern-keyed RBAC matcher composable with the bearer middleware.
  • Authentication — principal + authorities tuple persisted on the context for downstream handlers and CQRS handlers alike.

Mental model

                    incoming request
                            │
                            ▼
        ┌──────────────────────────────────────┐
        │       BearerMiddleware                │
        │  • reads Authorization: Bearer <tok>  │
        │  • calls Verifier (idp adapter)       │
        │  • stores Authentication on ctx       │
        │  • 401 application/problem+json on err│
        └──────────────────────────────────────┘
                            │
                            ▼
        ┌──────────────────────────────────────┐
        │        FilterChain.Middleware()       │
        │  Permit(prefix)              → public │
        │  Require(prefix, roles...)   → RBAC   │
        │  401 / 403 problem+json on miss       │
        └──────────────────────────────────────┘
                            │
                            ▼
                       your handlers
                  (read MustAuthFrom(ctx))

Public surface

type Authentication struct {
    Principal string         // unique stable id (sub claim)
    Username  string
    Roles     []string
    Claims    map[string]any
}
func (Authentication) HasRole(string) bool
func (Authentication) HasAnyRole(...string) bool

const AnonymousID = "anonymous"

type Verifier interface {
    Verify(ctx, token string) (Authentication, error)
}
type VerifierFunc func(ctx, token string) (Authentication, error)

var ErrUnauthenticated = errors.New("…unauthenticated")
var ErrForbidden       = errors.New("…forbidden")

func WithAuthentication(ctx, Authentication) context.Context
func AuthenticationFrom(ctx) (Authentication, bool)
func MustAuthFrom(ctx) Authentication

type BearerConfig struct {
    Verifier         Verifier
    AllowAnonymous   bool
    HeaderName       string
    UnauthorizedFunc func(http.ResponseWriter, *http.Request, error)
}
func BearerMiddleware(BearerConfig) func(http.Handler) http.Handler

type FilterChain struct{ ... }
func NewFilterChain() *FilterChain
func (*FilterChain) Permit(prefix) *FilterChain
func (*FilterChain) PermitMethod(method, prefix) *FilterChain
func (*FilterChain) Require(prefix, roles...) *FilterChain
func (*FilterChain) Middleware() func(http.Handler) http.Handler

Wiring with the IDP module

idp.Adapter exposes Validate(ctx, accessToken) (User, error). Adapt it to a security.Verifier:

verifier := security.VerifierFunc(func(ctx context.Context, token string) (security.Authentication, error) {
    u, err := idpAdapter.Validate(ctx, token)
    if err != nil { return security.Authentication{}, err }
    return security.Authentication{
        Principal: u.ID,
        Username:  u.Username,
        Roles:     u.Roles,
    }, nil
})

Quick start

chain := security.NewFilterChain().
    Permit("/actuator/health").
    Permit("/actuator/info").
    Require("/admin/", "ADMIN").
    Require("/api/", "USER", "ADMIN")

mux := http.NewServeMux()
// … register routes …

bearer := security.BearerMiddleware(security.BearerConfig{Verifier: verifier})
http.ListenAndServe(":8080", bearer(chain.Middleware()(mux)))

In handlers:

auth := security.MustAuthFrom(r.Context())
if !auth.HasAnyRole("ADMIN", "OPERATOR") {
    web.WriteProblem(w, kernel.ProblemForbidden("must be admin/operator"))
    return
}

Testing

cd security
go test ./...

Covers happy-path token verification, malformed-header 401, the anonymous fallthrough mode, and the filter-chain permit / require / forbidden matrix.