Claude-skill-registry customization

Configure middleware extension hooks for affolterNET.Web.Bff. Use when adding custom middleware, extending the pipeline, or integrating third-party components.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/customization" ~/.claude/skills/majiayu000-claude-skill-registry-customization && rm -rf "$T"
manifest: skills/data/customization/SKILL.md
source content

Customization Hooks

Extend the BFF middleware pipeline with custom components.

For complete reference, see Library Guide.

Extension Points

The BFF provides two middleware hooks:

HookPositionUse Case
ConfigureAfterRoutingCustomMiddleware
After routingTenant resolution, request context
ConfigureBeforeEndpointsCustomMiddleware
Before endpointsAudit logging, final validation

Quick Start

var options = builder.Services.AddBffServices(isDev, config, opts => {
    opts.ConfigureAfterRoutingCustomMiddleware = app => {
        app.UseMiddleware<TenantMiddleware>();
        app.UseMiddleware<RequestContextMiddleware>();
    };

    opts.ConfigureBeforeEndpointsCustomMiddleware = app => {
        app.UseMiddleware<AuditMiddleware>();
    };
});

Middleware Pipeline Position

1. Exception Handling
2. Security Headers
3. HTTPS Redirection
4. Static Files
5. Swagger
6. Routing
7. ══► ConfigureAfterRoutingCustomMiddleware ◄══
8. CORS
9. Antiforgery
10. Authentication & Authorization
11. Token Refresh
12. RPT Middleware
13. NoUnauthorizedRedirect
14. Antiforgery Token
15. ══► ConfigureBeforeEndpointsCustomMiddleware ◄══
16. API 404 Handling
17. Endpoint Mapping

Example: Tenant Middleware

public class TenantMiddleware
{
    private readonly RequestDelegate _next;

    public TenantMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // Extract tenant from route or header
        var tenantId = context.Request.RouteValues["tenant"]?.ToString()
            ?? context.Request.Headers["X-Tenant-Id"].FirstOrDefault();

        if (!string.IsNullOrEmpty(tenantId))
        {
            context.Items["TenantId"] = tenantId;
        }

        await _next(context);
    }
}

Example: Audit Middleware

public class AuditMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<AuditMiddleware> _logger;

    public AuditMiddleware(RequestDelegate next, ILogger<AuditMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var userId = context.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        var path = context.Request.Path;
        var method = context.Request.Method;

        _logger.LogInformation("User {UserId} accessing {Method} {Path}",
            userId, method, path);

        await _next(context);
    }
}

Example: Request Timing

public class TimingMiddleware
{
    private readonly RequestDelegate _next;

    public TimingMiddleware(RequestDelegate next) => _next = next;

    public async Task InvokeAsync(HttpContext context)
    {
        var sw = Stopwatch.StartNew();

        context.Response.OnStarting(() => {
            sw.Stop();
            context.Response.Headers["X-Response-Time"] = $"{sw.ElapsedMilliseconds}ms";
            return Task.CompletedTask;
        });

        await _next(context);
    }
}

Accessing Services

public async Task InvokeAsync(HttpContext context, IMyService myService)
{
    // Services can be injected via InvokeAsync
    var result = await myService.DoSomethingAsync();
    await _next(context);
}

Troubleshooting

Middleware not executing

  • Verify hook is configured correctly
  • Check middleware order dependencies
  • Add logging to confirm registration

User claims not available

  • After-routing hook runs before authentication
  • Use before-endpoints hook for authenticated context