You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Azure OAuth或Azure API网关保护Open XPage REST API

基于Azure的Xpages REST API服务器到服务器认证保护方案

当前实现分析

你目前在Xpages的REST服务代码中直接通过Azure的JWKS端点验证Bearer令牌,这种方式可行但耦合性高,所有验证逻辑都嵌入业务代码,后续维护和扩展不便。以下是更优的替代保护方案:

方案一:Azure API网关前置认证

将Azure API网关部署在Xpages API前端,让网关全权承担OAuth令牌验证工作,具体步骤:

  • 配置API网关实例:创建网关并将后端指向你的Xpages API端点
  • 添加JWT验证策略:在网关的API操作中配置「验证JWT」策略,关键参数包括:
    • 令牌颁发者:https://login.microsoftonline.com/{租户ID}/v2.0
    • JWKS URI:https://login.microsoftonline.com/{租户ID}/discovery/v2.0/keys
    • 允许的受众:你的API对应的客户端ID或应用ID URI
  • 收紧后端访问权限:修改Xpages数据库权限,仅允许API网关的IP地址访问,取消Anonymous的直接访问权限,确保所有请求必须经过网关校验

这种方案的核心优势:

  • 业务代码无需处理认证逻辑,专注于业务实现
  • 网关统一处理令牌验证、限流、日志监控等横切需求
  • 后端API不直接暴露给外部,安全性大幅提升

方案二:结合Azure AD应用角色实现细粒度授权

如果需要更精准的权限控制,可以基于Azure AD应用角色扩展验证逻辑:

  1. 在Azure AD的API应用注册中添加自定义应用角色(例如LocationUpload.Write)
  2. 为调用API的客户端应用分配对应的应用角色
  3. 令牌验证时,额外检查roles声明是否包含所需权限

修改后的验证逻辑示例(中文注释):

<xe:restService pathInfo="locationupload">
    <xe:this.service>
        <xe:customRestService>
            <xe:this.doPost><![CDATA[#{javascript:try {
              // Azure JWKS公钥地址
              var azureDiscoveryKeys = "https://login.microsoftonline.com/租户ID/discovery/v2.0/keys";
              // 从请求头获取Bearer令牌
              var token = context.getRequest().getHeader("Authorization").replace("Bearer ", "");
              
              var provider = new UrlJwkProvider(new URL(azureDiscoveryKeys));
              var jwt = JWT.decode(token);
              var jwk = provider.get(jwt.getKeyId());
              var publicKey = (RSAPublicKey) jwk.getPublicKey();

              // 配置验证算法和规则
              var alg = Algorithm.RSA256(publicKey, null);
              var verifier = JWT.require(alg)
                  .withIssuer("https://login.microsoftonline.com/租户ID/v2.0")
                  .withAudience("你的API应用ID URI")
                  .build();

              var decodedJwt = verifier.verify(token);
              // 检查令牌中的应用角色权限
              var roles = decodedJwt.getClaim("roles").asList(String.class);
              if (!roles.contains("LocationUpload.Write")) {
                  throw new Exception("无权限访问该API");
              }
              System.out.println("令牌验证通过,权限检查通过");

            } catch(JWTVerificationException ex) {
                System.out.println("令牌验证失败:" + ex.getMessage());
                context.getResponse().setStatus(401);
            } catch(JwkException ex) {
                System.out.println("获取公钥失败:" + ex.getMessage());
                context.getResponse().setStatus(500);
            } catch(MalformedURLException ex) {
                System.out.println("JWKS URL格式错误:" + ex.getMessage());
                context.getResponse().setStatus(500);
            } catch(Exception e) {
                System.out.println("请求处理失败:" + e.getMessage());
                context.getResponse().setStatus(403);
                e.printStackTrace();
            }}]]></xe:this.doPost>
        </xe:customRestService>
    </xe:this.service>
</xe:restService>

方案三:Azure AD B2C(适配未来扩展场景)

若后续需要支持用户参与的认证流程,可以考虑Azure AD B2C,但当前服务器到服务器无交互场景下必要性较低。

关键注意事项

  • 令牌获取方式:确保客户端使用「客户端凭据流」(Client Credentials Flow)获取令牌,这是无用户交互场景的标准OAuth 2.0流程
  • 权限最小化原则:收紧Xpages数据库权限,避免Anonymous权限过大;若使用API网关,仅开放网关IP的访问权限
  • 性能优化:当前代码每次请求都拉取JWKS公钥,建议添加缓存逻辑,减少对Azure端点的重复请求

内容的提问来源于stack exchange,提问作者Vijayakumar Oorappan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 18:23:31