GoBeegoCasbinFilter
Part of GoAuthTagger: a beego filter that authorizes every request
against a Casbin policy.
web.InsertFilter("*", web.BeforeRouter, routers.ApiFilter) func ApiFilter(ctx *context.Context) { allowed, _ := authz.IsAllowed(getSubject(ctx), urlPath, ...) if !allowed { denyRequest(ctx) } // ctx.Output.JSON(...) } func getSubject(ctx) string { if user == "" { return "anonymous" } ... } // authz: Enforcer.Enforce(...), policy loaded from a literal: p, *, POST, /api/signup
A filter counts only when all of these hold:
- it runs before the controller (
BeforeStatic,BeforeRouter,BeforeExec), registered by a live (uncommented)InsertFilter; each registration keeps its own pattern; - its body (or a function it calls, two hops) calls a Casbin
Enforce; - it writes a response under a negated test (
if !allowed {): a 401/403, or anOutput/ResponseWriterwrite orAbort, in the block or in a same-package function it calls (two hops) — a flag or a comment is not a refusal; - an anonymous caller reaches that test: no earlier
if token == "" { return }in the filter lets a request without a credential through.
The policy is a Go raw string (or, when no raw string holds one, a .csv
/ .conf file) of p, ... lines in the same Go module, read through the
model definition whose path field the lines fill with paths. Its effect
must be the plain allow-override (some(where (p.eft == allow))); a
deny row grants nothing, and any other effect leaves the filter unread.
A line grants anonymous access when every subject field is *, the
subject the filter passes for a caller without a session (return "anonymous" / user = "guest" under an absence test), or a role that
subject has through g lines, and its other fields are *. A path is
compared with keyMatch2 after the folds the filter itself applies
(if strings.HasPrefix(p, "/scim") { return "/scim" }). Every other route
under the filter's pattern, in a program whose main package registers
the filter (or imports the package that does), is guarded.
Constants
A request with no credential: !ok, token == "", u == nil, len(t) == 0.
A function head's parameter list, and a beego *context.Context or an
http.ResponseWriter parameter in it.
The import paths of a Go file, read off its import block with no parse:
program_dirs walks every file of the program.
A log, print or audit line names a refusal without making one.
A response written: beego's ctx.Output / ResponseWriter, an abort.
A response written on the request: a call on the request context or
writer (ctx.Output.JSON(...), ctx.Abort(403, ""), w.WriteHeader(403)),
the receiver captured so it can be checked against the function's own
context / writer parameters.