Modern enterprise APIs require robust security mechanisms that provide fine-grained access control while maintaining scalability and user experience. This comprehensive guide covers advanced API security implementations using OAuth 2.0 and OpenID Connect, including secure authentication flows, token lifecycle management, and enterprise-grade protection strategies for distributed systems.

Advanced API Security and OAuth 2.0/OIDC Implementation

Section 1: OAuth 2.0 and OIDC Security Architecture

OAuth 2.0 provides authorization framework while OpenID Connect adds authentication layer, together forming the foundation for modern API security implementations.

Enterprise OAuth 2.0 Authorization Server

// oauth-server.go
package main

import (
    "context"
    "crypto/rsa"
    "encoding/json"
    "fmt"
    "net/http"
    "time"
    
    "github.com/golang-jwt/jwt/v5"
    "github.com/google/uuid"
)

type OAuth2Server struct {
    clients        ClientStore
    tokens         TokenStore
    users          UserStore
    signingKey     *rsa.PrivateKey
    verifyingKey   *rsa.PublicKey
    tokenGenerator TokenGenerator
    flows          map[string]AuthorizationFlow
}

type Client struct {
    ID            string   `json:"client_id"`
    Secret        string   `json:"client_secret,omitempty"`
    Name          string   `json:"client_name"`
    RedirectURIs  []string `json:"redirect_uris"`
    GrantTypes    []string `json:"grant_types"`
    ResponseTypes []string `json:"response_types"`
    Scopes        []string `json:"scope"`
    TokenEndpointAuthMethod string `json:"token_endpoint_auth_method"`
    JWKsURI       string   `json:"jwks_uri,omitempty"`
    PublicKey     string   `json:"public_key,omitempty"`
    Confidential  bool     `json:"confidential"`
    Trusted       bool     `json:"trusted"`
    CreatedAt     time.Time `json:"created_at"`
    UpdatedAt     time.Time `json:"updated_at"`
}

type AccessToken struct {
    Value     string    `json:"access_token"`
    Type      string    `json:"token_type"`
    ExpiresIn int64     `json:"expires_in"`
    ExpiresAt time.Time `json:"expires_at"`
    Scope     string    `json:"scope"`
    ClientID  string    `json:"client_id"`
    UserID    string    `json:"user_id,omitempty"`
    JTI       string    `json:"jti"`
    Audience  []string  `json:"aud"`
    Issuer    string    `json:"iss"`
    Subject   string    `json:"sub"`
}

type AuthorizationCode struct {
    Code        string    `json:"code"`
    ClientID    string    `json:"client_id"`
    UserID      string    `json:"user_id"`
    RedirectURI string    `json:"redirect_uri"`
    Scope       string    `json:"scope"`
    Challenge   string    `json:"code_challenge,omitempty"`
    ChallengeMethod string `json:"code_challenge_method,omitempty"`
    ExpiresAt   time.Time `json:"expires_at"`
    Used        bool      `json:"used"`
}

type TokenRequest struct {
    GrantType    string `form:"grant_type" json:"grant_type"`
    Code         string `form:"code" json:"code,omitempty"`
    RedirectURI  string `form:"redirect_uri" json:"redirect_uri,omitempty"`
    ClientID     string `form:"client_id" json:"client_id"`
    ClientSecret string `form:"client_secret" json:"client_secret,omitempty"`
    Username     string `form:"username" json:"username,omitempty"`
    Password     string `form:"password" json:"password,omitempty"`
    Scope        string `form:"scope" json:"scope,omitempty"`
    RefreshToken string `form:"refresh_token" json:"refresh_token,omitempty"`
    CodeVerifier string `form:"code_verifier" json:"code_verifier,omitempty"`
}

// Authorization Code Flow with PKCE
type AuthorizationCodeFlow struct {
    server *OAuth2Server
}

func (acf *AuthorizationCodeFlow) HandleAuthorize(w http.ResponseWriter, r *http.Request) {
    params := r.URL.Query()
    
    clientID := params.Get("client_id")
    redirectURI := params.Get("redirect_uri")
    scope := params.Get("scope")
    state := params.Get("state")
    codeChallenge := params.Get("code_challenge")
    codeChallengeMethod := params.Get("code_challenge_method")
    
    // Validate client
    client, err := acf.server.clients.GetClient(clientID)
    if err != nil {
        http.Error(w, "Invalid client", http.StatusBadRequest)
        return
    }
    
    // Validate redirect URI
    if !acf.validateRedirectURI(client, redirectURI) {
        http.Error(w, "Invalid redirect URI", http.StatusBadRequest)
        return
    }
    
    // Validate PKCE parameters
    if client.Confidential && codeChallenge == "" {
        acf.redirectWithError(w, redirectURI, "invalid_request", "code_challenge required", state)
        return
    }
    
    // Check if user is authenticated
    userID := acf.getUserFromSession(r)
    if userID == "" {
        // Redirect to login
        acf.redirectToLogin(w, r, clientID, redirectURI, scope, state, codeChallenge, codeChallengeMethod)
        return
    }
    
    // Check user consent
    if !acf.hasValidConsent(userID, clientID, scope) {
        // Show consent screen
        acf.showConsentScreen(w, r, client, scope, userID)
        return
    }
    
    // Generate authorization code
    code := &AuthorizationCode{\n        Code:            generateSecureCode(),\n        ClientID:        clientID,\n        UserID:          userID,\n        RedirectURI:     redirectURI,\n        Scope:           scope,\n        Challenge:       codeChallenge,\n        ChallengeMethod: codeChallengeMethod,\n        ExpiresAt:       time.Now().Add(10 * time.Minute),\n    }\n    \n    if err := acf.server.tokens.StoreAuthorizationCode(code); err != nil {\n        http.Error(w, \"Internal server error\", http.StatusInternalServerError)\n        return\n    }\n    \n    // Redirect with authorization code\n    acf.redirectWithCode(w, redirectURI, code.Code, state)\n}\n\nfunc (acf *AuthorizationCodeFlow) HandleToken(w http.ResponseWriter, r *http.Request) {\n    var req TokenRequest\n    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {\n        acf.tokenError(w, \"invalid_request\", \"Invalid request format\")\n        return\n    }\n    \n    // Authenticate client\n    client, err := acf.authenticateClient(req.ClientID, req.ClientSecret, r)\n    if err != nil {\n        acf.tokenError(w, \"invalid_client\", \"Client authentication failed\")\n        return\n    }\n    \n    switch req.GrantType {\n    case \"authorization_code\":\n        acf.handleAuthorizationCodeGrant(w, req, client)\n    case \"refresh_token\":\n        acf.handleRefreshTokenGrant(w, req, client)\n    case \"client_credentials\":\n        acf.handleClientCredentialsGrant(w, req, client)\n    default:\n        acf.tokenError(w, \"unsupported_grant_type\", \"Grant type not supported\")\n    }\n}\n\nfunc (acf *AuthorizationCodeFlow) handleAuthorizationCodeGrant(w http.ResponseWriter, req TokenRequest, client *Client) {\n    // Validate authorization code\n    code, err := acf.server.tokens.GetAuthorizationCode(req.Code)\n    if err != nil || code.Used || time.Now().After(code.ExpiresAt) {\n        acf.tokenError(w, \"invalid_grant\", \"Invalid authorization code\")\n        return\n    }\n    \n    // Validate client ID\n    if code.ClientID != client.ID {\n        acf.tokenError(w, \"invalid_grant\", \"Client ID mismatch\")\n        return\n    }\n    \n    // Validate redirect URI\n    if code.RedirectURI != req.RedirectURI {\n        acf.tokenError(w, \"invalid_grant\", \"Redirect URI mismatch\")\n        return\n    }\n    \n    // Validate PKCE\n    if code.Challenge != \"\" {\n        if !acf.validatePKCE(code.Challenge, code.ChallengeMethod, req.CodeVerifier) {\n            acf.tokenError(w, \"invalid_grant\", \"PKCE validation failed\")\n            return\n        }\n    }\n    \n    // Mark code as used\n    code.Used = true\n    acf.server.tokens.UpdateAuthorizationCode(code)\n    \n    // Generate access token\n    accessToken := acf.generateAccessToken(client, code.UserID, code.Scope)\n    refreshToken := acf.generateRefreshToken(client, code.UserID, code.Scope)\n    \n    response := map[string]interface{}{\n        \"access_token\":  accessToken.Value,\n        \"token_type\":    \"Bearer\",\n        \"expires_in\":    accessToken.ExpiresIn,\n        \"refresh_token\": refreshToken,\n        \"scope\":         accessToken.Scope,\n    }\n    \n    w.Header().Set(\"Content-Type\", \"application/json\")\n    w.Header().Set(\"Cache-Control\", \"no-store\")\n    w.Header().Set(\"Pragma\", \"no-cache\")\n    json.NewEncoder(w).Encode(response)\n}\n\n// OpenID Connect Implementation\ntype OIDCProvider struct {\n    oauth2Server *OAuth2Server\n    userInfo     UserInfoEndpoint\n    discovery    DiscoveryDocument\n    jwks         JWKSEndpoint\n}\n\ntype IDToken struct {\n    Issuer          string `json:\"iss\"`\n    Subject         string `json:\"sub\"`\n    Audience        string `json:\"aud\"`\n    ExpiresAt       int64  `json:\"exp\"`\n    IssuedAt        int64  `json:\"iat\"`\n    AuthTime        int64  `json:\"auth_time,omitempty\"`\n    Nonce           string `json:\"nonce,omitempty\"`\n    Email           string `json:\"email,omitempty\"`\n    EmailVerified   bool   `json:\"email_verified,omitempty\"`\n    Name            string `json:\"name,omitempty\"`\n    PreferredUsername string `json:\"preferred_username,omitempty\"`\n    Groups          []string `json:\"groups,omitempty\"`\n}\n\nfunc (oidc *OIDCProvider) GenerateIDToken(user *User, client *Client, nonce string) (string, error) {\n    now := time.Now()\n    \n    claims := IDToken{\n        Issuer:    \"https://auth.company.com\",\n        Subject:   user.ID,\n        Audience:  client.ID,\n        ExpiresAt: now.Add(1 * time.Hour).Unix(),\n        IssuedAt:  now.Unix(),\n        AuthTime:  user.LastAuthTime.Unix(),\n        Nonce:     nonce,\n        Email:     user.Email,\n        EmailVerified: user.EmailVerified,\n        Name:      user.Name,\n        PreferredUsername: user.Username,\n        Groups:    user.Groups,\n    }\n    \n    token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)\n    token.Header[\"kid\"] = \"key-1\"\n    \n    return token.SignedString(oidc.oauth2Server.signingKey)\n}\n\nfunc (oidc *OIDCProvider) HandleUserInfo(w http.ResponseWriter, r *http.Request) {\n    // Extract bearer token\n    authHeader := r.Header.Get(\"Authorization\")\n    if !strings.HasPrefix(authHeader, \"Bearer \") {\n        http.Error(w, \"Unauthorized\", http.StatusUnauthorized)\n        return\n    }\n    \n    tokenValue := strings.TrimPrefix(authHeader, \"Bearer \")\n    \n    // Validate access token\n    token, err := oidc.oauth2Server.tokens.ValidateAccessToken(tokenValue)\n    if err != nil {\n        http.Error(w, \"Invalid token\", http.StatusUnauthorized)\n        return\n    }\n    \n    // Get user info\n    user, err := oidc.oauth2Server.users.GetUser(token.UserID)\n    if err != nil {\n        http.Error(w, \"User not found\", http.StatusNotFound)\n        return\n    }\n    \n    // Build user info response based on scope\n    userInfo := oidc.buildUserInfoResponse(user, token.Scope)\n    \n    w.Header().Set(\"Content-Type\", \"application/json\")\n    json.NewEncoder(w).Encode(userInfo)\n}\n\n// API Gateway Integration\ntype APIGateway struct {\n    oauth2Server   *OAuth2Server\n    rateLimiter    *RateLimiter\n    routes         map[string]*Route\n    middleware     []Middleware\n    metrics        *MetricsCollector\n}\n\ntype Route struct {\n    Path        string\n    Method      string\n    Handler     http.HandlerFunc\n    Scopes      []string\n    RateLimit   *RateLimit\n    Timeout     time.Duration\n    RequireAuth bool\n}\n\ntype Middleware interface {\n    Process(next http.HandlerFunc) http.HandlerFunc\n}\n\ntype AuthenticationMiddleware struct {\n    oauth2Server *OAuth2Server\n}\n\nfunc (am *AuthenticationMiddleware) Process(next http.HandlerFunc) http.HandlerFunc {\n    return func(w http.ResponseWriter, r *http.Request) {\n        // Extract token from Authorization header\n        authHeader := r.Header.Get(\"Authorization\")\n        if authHeader == \"\" {\n            http.Error(w, \"Missing authorization header\", http.StatusUnauthorized)\n            return\n        }\n        \n        if !strings.HasPrefix(authHeader, \"Bearer \") {\n            http.Error(w, \"Invalid authorization header format\", http.StatusUnauthorized)\n            return\n        }\n        \n        tokenValue := strings.TrimPrefix(authHeader, \"Bearer \")\n        \n        // Validate token\n        token, err := am.oauth2Server.tokens.ValidateAccessToken(tokenValue)\n        if err != nil {\n            http.Error(w, \"Invalid or expired token\", http.StatusUnauthorized)\n            return\n        }\n        \n        // Add token info to request context\n        ctx := context.WithValue(r.Context(), \"token\", token)\n        ctx = context.WithValue(ctx, \"user_id\", token.UserID)\n        ctx = context.WithValue(ctx, \"client_id\", token.ClientID)\n        ctx = context.WithValue(ctx, \"scopes\", strings.Split(token.Scope, \" \"))\n        \n        next(w, r.WithContext(ctx))\n    }\n}\n\ntype AuthorizationMiddleware struct {}\n\nfunc (azm *AuthorizationMiddleware) Process(next http.HandlerFunc) http.HandlerFunc {\n    return func(w http.ResponseWriter, r *http.Request) {\n        // Get required scopes for this route\n        route := getRouteFromContext(r.Context())\n        if route == nil || len(route.Scopes) == 0 {\n            next(w, r)\n            return\n        }\n        \n        // Get user scopes from token\n        tokenScopes, ok := r.Context().Value(\"scopes\").([]string)\n        if !ok {\n            http.Error(w, \"No scopes found in token\", http.StatusForbidden)\n            return\n        }\n        \n        // Check if user has required scopes\n        if !hasRequiredScopes(tokenScopes, route.Scopes) {\n            http.Error(w, \"Insufficient scopes\", http.StatusForbidden)\n            return\n        }\n        \n        next(w, r)\n    }\n}\n\n// JWT Token Security\ntype JWTSecurity struct {\n    signingKey    *rsa.PrivateKey\n    verifyingKeys map[string]*rsa.PublicKey\n    algorithms    []string\n    leeway        time.Duration\n}\n\nfunc NewJWTSecurity() *JWTSecurity {\n    return &JWTSecurity{\n        verifyingKeys: make(map[string]*rsa.PublicKey),\n        algorithms:    []string{\"RS256\", \"RS384\", \"RS512\"},\n        leeway:        30 * time.Second,\n    }\n}\n\nfunc (js *JWTSecurity) ValidateJWT(tokenString string) (*jwt.Token, error) {\n    token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {\n        // Verify signing method\n        if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {\n            return nil, fmt.Errorf(\"unexpected signing method: %v\", token.Header[\"alg\"])\n        }\n        \n        // Get key ID from header\n        kid, ok := token.Header[\"kid\"].(string)\n        if !ok {\n            return nil, fmt.Errorf(\"missing key ID in token header\")\n        }\n        \n        // Get verification key\n        verifyingKey, exists := js.verifyingKeys[kid]\n        if !exists {\n            return nil, fmt.Errorf(\"unknown key ID: %s\", kid)\n        }\n        \n        return verifyingKey, nil\n    })\n    \n    if err != nil {\n        return nil, err\n    }\n    \n    if !token.Valid {\n        return nil, fmt.Errorf(\"invalid token\")\n    }\n    \n    return token, nil\n}\n\n// Advanced Security Features\ntype SecurityEnhancement struct {\n    tokenBinding    *TokenBinding\n    dpop           *DPoP\n    mtls           *MutualTLS\n    jarValidation  *JARValidation\n}\n\n// Demonstration-of-Proof-of-Possession (DPoP)\ntype DPoP struct {\n    allowedAlgorithms []string\n    maxSkew          time.Duration\n}\n\nfunc (dpop *DPoP) ValidateDPoPProof(proof string, method string, url string, accessToken string) error {\n    token, err := jwt.Parse(proof, func(token *jwt.Token) (interface{}, error) {\n        // Validate algorithm\n        alg, ok := token.Header[\"alg\"].(string)\n        if !ok {\n            return nil, fmt.Errorf(\"missing algorithm in DPoP proof\")\n        }\n        \n        if !contains(dpop.allowedAlgorithms, alg) {\n            return nil, fmt.Errorf(\"unsupported algorithm: %s\", alg)\n        }\n        \n        // Extract public key from JWK\n        jwk, ok := token.Header[\"jwk\"]\n        if !ok {\n            return nil, fmt.Errorf(\"missing JWK in DPoP proof\")\n        }\n        \n        return parseJWKToPublicKey(jwk)\n    })\n    \n    if err != nil {\n        return err\n    }\n    \n    claims, ok := token.Claims.(jwt.MapClaims)\n    if !ok {\n        return fmt.Errorf(\"invalid claims format\")\n    }\n    \n    // Validate claims\n    if claims[\"htm\"] != method {\n        return fmt.Errorf(\"HTTP method mismatch\")\n    }\n    \n    if claims[\"htu\"] != url {\n        return fmt.Errorf(\"HTTP URI mismatch\")\n    }\n    \n    // Validate timestamp\n    iat, ok := claims[\"iat\"].(float64)\n    if !ok {\n        return fmt.Errorf(\"missing issued at claim\")\n    }\n    \n    issuedAt := time.Unix(int64(iat), 0)\n    if time.Now().Sub(issuedAt) > dpop.maxSkew {\n        return fmt.Errorf(\"DPoP proof too old\")\n    }\n    \n    return nil\n}\n\n// Token Introspection\ntype TokenIntrospection struct {\n    oauth2Server *OAuth2Server\n}\n\nfunc (ti *TokenIntrospection) HandleIntrospection(w http.ResponseWriter, r *http.Request) {\n    // Authenticate client\n    clientID, clientSecret, ok := r.BasicAuth()\n    if !ok {\n        http.Error(w, \"Unauthorized\", http.StatusUnauthorized)\n        return\n    }\n    \n    client, err := ti.oauth2Server.clients.AuthenticateClient(clientID, clientSecret)\n    if err != nil {\n        http.Error(w, \"Invalid client credentials\", http.StatusUnauthorized)\n        return\n    }\n    \n    // Get token from request\n    tokenValue := r.FormValue(\"token\")\n    if tokenValue == \"\" {\n        http.Error(w, \"Missing token parameter\", http.StatusBadRequest)\n        return\n    }\n    \n    // Introspect token\n    response := ti.introspectToken(tokenValue, client)\n    \n    w.Header().Set(\"Content-Type\", \"application/json\")\n    json.NewEncoder(w).Encode(response)\n}\n\nfunc (ti *TokenIntrospection) introspectToken(tokenValue string, client *Client) map[string]interface{} {\n    token, err := ti.oauth2Server.tokens.ValidateAccessToken(tokenValue)\n    if err != nil {\n        return map[string]interface{}{\"active\": false}\n    }\n    \n    response := map[string]interface{}{\n        \"active\":     true,\n        \"scope\":      token.Scope,\n        \"client_id\":  token.ClientID,\n        \"username\":   token.UserID,\n        \"token_type\": token.Type,\n        \"exp\":        token.ExpiresAt.Unix(),\n        \"iat\":        token.ExpiresAt.Add(-time.Duration(token.ExpiresIn)*time.Second).Unix(),\n        \"sub\":        token.Subject,\n        \"aud\":        token.Audience,\n        \"iss\":        token.Issuer,\n        \"jti\":        token.JTI,\n    }\n    \n    return response\n}\n```\n\nThis comprehensive API security guide provides enterprise-grade OAuth 2.0 and OpenID Connect implementations with advanced security features including PKCE, DPoP, token introspection, and JWT security. Organizations should implement these patterns to ensure robust API protection while maintaining scalability and compliance with modern security standards.