package aceboot::security
import aceboot::web.*
/** 路由授权策略:HTTP 方法(* 通配)+ 路径前缀 → 要求拥有任一角色。 */
public struct RolePolicy {
public let method: String
public let pathPrefix: String
public let roles: Array<String>
public init(method: String, pathPrefix: String, roles: Array<String>) {
this.method = method
this.pathPrefix = pathPrefix
this.roles = roles
}
}
/**
* 路由授权中间件(经 @Middleware 注册插入):对命中策略的请求要求角色,无权限 -> 403。
* 依赖认证中间件已写入 Principal(jwtAuth);命中的多条策略全部要求(AND)。
* 这是「路由级鉴权」的第三方实现——核心框架不内置安全逻辑。
*/
public func authorize(policies: Array<RolePolicy>): Middleware {
return {
ctx, next =>
for (p in policies) {
if ((p.method == "*" || p.method == ctx.method) && ctx.path.startsWith(p.pathPrefix)) {
enforcePolicy(ctx, p.roles)
}
}
next()
}
}
func enforcePolicy(ctx: Context, required: Array<String>): Unit {
let have = match (currentPrincipal(ctx)) {
case Some(pp) => pp.roles
case None => throw HttpError(401, "authentication required")
}
for (need in required) {
for (h in have) {
if (h == need) {
return
}
}
}
throw HttpError(403, "insufficient permissions")
}