服务间认证疑问:Java MSAL中应使用调用方还是被调用方的Service Principal?
服务到服务认证中的Service Principal选择与权限控制(Java MSAL)
1. Service Principal的归属与选择
在服务到服务的认证场景中:
- 调用方应用必须使用自己的Service Principal(SP):调用方需要用自身的SP凭证(客户端密钥/证书)向Azure AD请求访问令牌,这个凭证是调用方独有的,绝对不能共享给其他应用。
- 被调用方应用也有自己的SP:你在示例中看到硬编码在配置里的,通常是被调用方的SP信息(比如客户端ID、API范围,格式类似
api://{被调用方SP-ID}/.default),这是用来告诉MSAL要请求哪个服务的访问权限,而非被调用方的敏感凭证。
简单总结:调用方用自己的SP拿令牌,被调用方的SP信息是公开的访问标识,无需保密。
2. 是否需要共享被调用方的Service Principal?
不需要。被调用方的SP凭证(密钥/证书)是用于自身认证的(比如被调用方要调用其他服务时),绝对不能对外共享。而被调用方的SP客户端ID、API范围这类信息,就像API的访问地址一样属于公开信息,调用方只需要知道这些信息来构造令牌请求即可。
3. 如何限制部分应用的访问权限?
可以通过以下步骤实现细粒度的权限控制:
- 定义应用权限:在Azure AD的被调用方API注册中,添加自定义应用权限(比如
Order.Read.All、Order.Write.All),这类权限专门服务于服务到服务场景(区别于用户委派权限)。 - 分配权限给指定调用方:在Azure AD中找到被调用方的API,进入「权限」页面,为需要访问的调用方SP分配对应的应用权限。未被分配权限的调用方,无法获取到包含对应权限的访问令牌。
- 在被调用方代码中验证权限:当收到调用方的请求时,解析JWT令牌中的
roles声明,检查是否包含允许的权限。示例代码如下:
// 解析令牌并提取roles声明 Jwt jwt = Jwt.decode(token); List<String> roles = jwt.getClaim("roles").asList(String.class); if (!roles.contains("Order.Read.All")) { throw new SecurityException("无访问权限"); }
- 额外限制:条件访问策略:如果需要更严格的控制(比如限制调用方的IP范围、设备状态),可以在Azure AD中创建条件访问策略,针对被调用方的API设置访问规则。
内容的提问来源于stack exchange,提问作者Onki
相关产品推荐
相关产品推荐

