Api Filters
Description
Attribute-based request filters for access control on controllers and actions. Built on top of BaseApiFilterAttribute which provides flexible value matching via exact string, wildcard, pipe-delimited or regex patterns.
Features
- ApiTokenFilter: validates the
api-tokenrequest header (or custom header name) - OriginFilter: validates the
Originrequest header - UserAgentFilter: validates the
User-Agentrequest header — also blocks known bots, crawlers and spiders automatically when applied - BaseApiFilterAttribute: base class for building custom filter attributes with built-in header value matching
Behavior
All filters use the same matching logic inherited from BaseApiFilterAttribute, evaluated in this order:
nullor*→ allows all- Exact string → case-sensitive match
- Pipe-delimited
a|b→ case-insensitive contains match against any part - Wildcard
*text*→ case-insensitive starts/ends/contains match - Regex
^pattern$→ compiled withRegexOptions.IgnoreCase— always case-insensitive
On access denied, returns HTTP 403 with a JSON error body.
Caveats
- Regex matching silently falls back to no-match if the pattern is invalid — no exception is thrown
ApiTokenFilterdefaults toapi-tokenheader name but accepts any custom header nameUserAgentFilterblocks known bots and crawlers regardless of the match pattern — adding the attribute always enables bot blocking- Filters return
application/jsonon access denied — plain text and XML responses not yet supported
Tip
- Inherit
BaseApiFilterAttributeto build your own filter attributes — overrideOnActionExecutingand useRequestHasValidHeaderValueandOnAccessDeniedfor consistent behavior. - Multiple attributes on the same controller are AND'd — every filter must pass. Use pipe-delimited values for OR logic, for instance:
[ApiTokenFilter("token1|token2|token3")]
Examples
[ApiTokenFilter("SecretToken")]
[OriginFilter("*.systemlibrary.com")]
[UserAgentFilter("Chrome|Edg|Firefox")]
public class OrderController : BaseApiController { }
[ApiTokenFilter("^DEV-[A-Z0-9]{6}$")]
public ActionResult SensitiveEndpoint() { }