身份与权限:Bella OpenAPI 的认证授权体系
引言:企业级安全架构的重要性
在 AI 服务日益普及的今天,API 网关不仅需要提供丰富的功能,还必须建立严格的身份认证和访问控制机制,确保企业数据安全和合规使用。Bella OpenAPI 通过其多层次认证授权体系,成功解决了这一挑战。本文将基于对 Bella OpenAPI 源代码的深入分析,揭示其身份与权限管理的核心设计 和实现细节。
多元化的认证机制
通过分析 Bella OpenAPI 的源代码,我们发现系统支持多种认证方式,满足不同使用场景的需求:
1. API Key 认证
API Key 认证是 Bella OpenAPI 最核心的认证机制,特别适用于系统间集成和自动化场景:
// LoginFilter.java
if(StringUtils.isNotBlank(properties.getAuthorizationHeader())) {
String auth =
httpRequest.getHeader(properties.getAuthorizationHeader());
if(StringUtils.isNotBlank(auth)) {
chain.doFilter(request, response);
return;
}
}
// ApikeyService.java
public ApikeyInfo verifyAuth(String auth) {
String ak;
if(auth.startsWith("Bearer ")) {
ak = auth.substring(7);
} else {
ak = auth;
}
String sha = EncryptUtils.sha256(ak);
ApikeyInfo info = queryBySha(sha, true);
// ...验证逻辑
return info;
}
系统使用 Bearer Token 格式传递 API Key,主要用于 API 调用的场景,并通过 SHA-256 哈希存储,确保即使在数据库泄露的情况下原始密钥也不会被暴露。
2. OAuth 认证和 CAS 支持
对于 web 交互场景,系统支持 OAuth 2.0 认证流程,集成了多个身份提供商,同时支持接入企业的 CAS 服务:
// ProviderConditional.java
@ConditionalOnOAuthEnable
@Conditional(ConditionalOnGoogleAuthEnable.GoogleAuthEnableCondition.class)
public @interface ConditionalOnGoogleAuthEnable {
// Google OAuth 条件判定
}
@ConditionalOnOAuthEnable
@Conditional(ConditionalOnGithubAuthEnable.GithubAuthEnableCondition.class)
public @interface ConditionalOnGithubAuthEnable {
// Github OAuth 条件判定
}
3. 父子关系设计
通过这种父子关系设计,企业级用户可以创建具有不同权限范围的子密钥,分配给不同的团队或外部合作伙伴,确保每个密钥只能访问必要的资源。
// ApikeyService.java
@Transactional
public String createByParentCode(ApikeyCreateOp op) {
ApikeyInfo apikey = EndpointContext.getApikey();
if(!apikey.getCode().equals(op.getParentCode())) {
throw new ChannelException.AuthorizationException("没有操作权限");
}
// 验证配额和安全级别
Assert.isTrue(op.getMonthQuota() == null ||
op.getMonthQuota().doubleValue() <=
apikey.getMonthQuota().doubleValue(), "配额超出 ak 的最大配额");
Assert.isTrue(op.getSafetyLevel() <= apikey.getSafetyLevel(),
"安全等级超出 ak 的最高等级");
// 创建子密钥
// ...
// 验证权限范围
if(CollectionUtils.isNotEmpty(op.getPaths())) {
boolean match = op.getPaths().stream().allMatch(url ->
apikey.getRolePath().getIncluded().stream().anyMatch(pattern ->
MatchUtils.matchUrl(pattern, url))
&&
apikey.getRolePath().getExcluded().stream().noneMatch(pattern ->
MatchUtils.matchUrl(pattern, url)));
Assert.isTrue(match, "超出 ak 的权限范围");
// ...
}
return ak;
}
4. 权限继承与约束
子密钥的权限受父密钥的严格约束,体现在多个维度:
- 访问路径约束:子密钥的访问路径必须是父密钥访问路径的子集
- 配额约束:子密钥的月度配额不能超过父密钥
- 安全级别约束:子密钥的安全级别不能高于父密钥
这种设计确保了权限委派过程中的安全性,防止通过创建子密钥绕过权限限制。
多维度的授权控制
Bella OpenAPI 实现了多维度的授权控制机制,确保精细化的权限管理:
1. 基于路径的访问控制
系统使用包含路径(included)和排除路径(excluded)的双重机制,实现精确的 URL 访问控制。这种设计允许管理员通过通配符模式灵活定义访问范围。
// ApikeyInfo.java
public boolean hasPermission(String url) {
return getRolePath().getIncluded().stream().anyMatch(pattern
-> MatchUtils.matchUrl(pattern, url))
&&
getRolePath().getExcluded().stream().noneMatch(pattern ->
MatchUtils.matchUrl(pattern, url));
}
2. 所有权类型区分
系统区分不同的所有权类型(个人、组织、系统),并据此实施不同的权限策略,满足企业内不同层次的权限管理需求。
// ApikeyInfo.java
private String ownerType;
private String ownerCode;
private String ownerName;
安全等级与数据保护
Bella OpenAPI 引入了安全等级概念,实现数据流向的合规控制:
// ChannelRouter.java (参考之前的分析)
private Byte getSafetyLevelLimit(String dataDestination) {
switch (dataDestination) {
case EntityConstants.PROTECTED:
return 10;
case EntityConstants.INNER:
return 20;
case EntityConstants.MAINLAND:
return 30;
case EntityConstants.OVERSEAS:
return 40;
}
return 40;
}
不同的数据流向要求不同的安全级别,确保敏感数据只流向合规的目的地:
- 已备案(PROTECTED):最低安全要求,10 级
- 内部(INNER):适中安全要求,20 级
- 大陆(MAINLAND):较高安全要求,30 级
- 海外(OVERSEAS):最高安全要求,40 级
这一机制对于企业级用户尤为重要
资源配额与使用监控
Bella OpenAPI 实现了完善的资源配额和使用监控机制:
使用情况查询
系统提供了便捷的使用情况查询接口,使企业可以分析 API 使用情况,优化资源分配。
// ApikeyService.java
public List<ApikeyMonthCostDB> queryBillingsByAkCode(String
akCode) {
return apikeyCostRepo.queryByAkCode(akCode);
}