Skip to content

Latest commit

 

History

History
139 lines (99 loc) · 3.97 KB

File metadata and controls

139 lines (99 loc) · 3.97 KB

Lib Auth Middleware

This repository contains an authorization middleware for the Fiber framework in Go, allowing you to check if a user is authorized to perform a specific action on a resource. The middleware sends a POST request to an authorization service, passing the user's details, resource, and desired action.

Repository: lib-auth

📦 Installation

go get -u github.com/LerianStudio/lib-auth/v2

🚀 How to Use

1. Set the needed environment variables:

In your environment configuration or .env file, set the following environment variables:

PLUGIN_AUTH_ADDRESS=http://localhost:4000
PLUGIN_AUTH_ENABLED=true

2. Create a new instance of the middleware:

In your config.go file, configure the environment variables for the Auth Service:

type Config struct {
    Address             string `env:"PLUGIN_AUTH_ADDRESS"`
    Enabled             bool   `env:"PLUGIN_AUTH_ENABLED"`
}

cfg := &Config{}

logger := zap.InitializeLogger()
import "github.com/LerianStudio/lib-auth/v2/auth/middleware"

authClient := middleware.NewAuthClient(cfg.Address, cfg.Enabled, &logger)

2. Use the middleware in your Fiber application:

func NewRoutes(auth *authMiddleware.AuthClient, [...]) *fiber.App {
    f := fiber.New(fiber.Config{
        DisableStartupMessage: true,
    })
    
    applicationName := os.Getenv("APPLICATION_NAME")
    
    // Applications routes
    f.Get("/v1/applications", auth.Authorize(applicationName, "ledger", "get"), applicationHandler.GetApplications)
}

🛠️ How It Works

The Authorize function:

  • Receives the sub (user), resource (resource), and action (desired action).
  • Sends a POST request to the authorization service.
  • Checks if the response indicates that the user is authorized.
  • Allows the normal application flow or returns a 403 (Forbidden) error.

📥 Example Request to Auth

POST /v1/authorize
Content-Type: application/json
Authorization: Bearer your_token_here

{
    "sub":      "lerian/userId",
    "resource": "resourceName",
    "action":   "get"
}

📡 Expected Authorization Service Response

The authorization service should return a JSON response in the following format:

{
    "authorized": true,
    "timestamp": "2025-03-03T12:00:00Z"
}

🔒 gRPC usage

Secure a gRPC server with the unary interceptor using per-method policies. It reuses the same auth service and tracing used by the HTTP middleware.

import (
    "context"
    "google.golang.org/grpc"
    "github.com/LerianStudio/lib-auth/v2/auth/middleware"
)

// Create the auth client once (same as HTTP)
authClient := middleware.NewAuthClient(cfg.Address, cfg.Enabled, &logger)

// Map full gRPC method names to authorization policies
policies := middleware.PolicyConfig{
    MethodPolicies: map[string]middleware.Policy{
        "/balance.BalanceProto/CreateBalance": {Resource: "balances", Action: "post"},
    },
    // Constant subject base, matching HTTP usage (e.g., "midaz")
    SubResolver: func(ctx context.Context, _ string, _ any) (string, error) { return "midaz", nil },
}

srv := grpc.NewServer(
    grpc.UnaryInterceptor(middleware.NewGRPCAuthUnaryPolicy(authClient, policies)),
)

Notes:

  • Keys in MethodPolicies must be full method names in the form /package.Service/Method.
  • When SubResolver returns an empty string, the subject is derived from token claims.
  • If you already use multiple interceptors, prefer grpc.ChainUnaryInterceptor(...) and include the auth interceptor alongside telemetry/logging.

🚧 Error Handling

The middleware captures and logs the following error types:

  • Failure to create the request
  • Failure to send the request
  • Failure to read the response body
  • Failure to deserialize the response JSON
  • Errors from the authorization service (e.g., 401 Unauthorized, 403 Forbidden)

📧 Contact

For questions or support, contact us at: contato@lerian.studio.