Azure AD中指定组访问Angular应用权限限制失效问题排查
问题描述
我正在开发一个Angular网站,使用MSAL做身份认证,Node.js端采用passport-azure-ad组件。在Azure AD注册Angular应用时,我创建了一个仅包含1个用户的组,并将该组添加到已注册的Angular应用中以限制专属访问,但当前租户内所有用户均可登录并访问受保护路由。
Node.js Token验证代码(authRouter.js)
// authRouter.js var express = require('express'); var router = express.Router(); var tokenValidationCache = new Map(); const azureConfig=require('../azure.conf.json') const passport = require('passport'); const BearerStrategy = require('passport-azure-ad').BearerStrategy; var languageController = require('../controllers/qnalanguage.controller'); const options = { identityMetadata: `https://${azureConfig.metadata.authority}/${azureConfig.credentials.tenantID}/${azureConfig.metadata.version}/${azureConfig.metadata.discovery}`, issuer: null, validateIssuer: azureConfig.settings.validateIssuer, clientID: azureConfig.credentials.clientID, audience: azureConfig.credentials.audience, passReqToCallback: azureConfig.settings.passReqToCallback, loggingLevel: azureConfig.settings.loggingLevel, scope: azureConfig.resource.scope, loggingNoPII: false, clockSkew: 300 }; const bearerStrategy = new BearerStrategy(options, (token, done) => { const roles = token.roles || []; const user = {}; return done(null, user, token); }); passport.use(bearerStrategy); router.use(passport.initialize()); router.use(passport.authenticate('oauth-bearer', { session: false }), (req, res, next) => { res.locals.authInfo = req.authInfo; return next(); }); router.get('/source', languageController.getQnAHtml); router.post('/knowledgebase', languageController.chatbotqaAdd); router.delete('/knowledgebase/:id', languageController.chatbotqaDelete); router.post('/knowledgebase/deploy', languageController.chatbotqaUpdateSource); router.post('/init', languageController.initMongoDbQNA); router.put('/knowledgebase',languageController.chatbotqaUpdate) router.get('/knowledgebase', languageController.getQNA); router.get('/protected',(req, res) => { res.send({'res':'Hello! This resource is protected.'}) } ) module.exports = router;
Angular相关代码
获取数据函数
fetchPosts() { let headers= new HttpHeaders() headers=headers.set('authorization','') this.http.get(`${this.baseurl}/api/v1/auth/knowledgebase`) .subscribe((posts:any)=>{console.log(posts) this.posts=posts}) }
MSAL拦截器配置
export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration { const protectedResourceMap = new Map<string, Array<string>>(); protectedResourceMap.set('https://graph.microsoft.com/v1.0/me', [...environment.apiConfig.scopes]); protectedResourceMap.set('http://www.localhost:8000/*',[...environment.apiConfig.scopes]) return { interactionType: InteractionType.Redirect, protectedResourceMap }; }
Node.js配置文件(azure.conf.json)
{ "credentials": { "tenantID": "tenantid", "clientID": "client id", "audience": "api://audience" }, "resource": { "scope": ["general"] }, "metadata": { "authority": "sts.windows.net", "discovery": ".well-known/openid-configuration", "version": "v2.0" }, "settings": { "validateIssuer": false, "passReqToCallback": false, "loggingLevel": "info" } }
Azure AD组分配截图

我需要实现仅允许指定组访问应用的功能,试过参考教程但未解决问题。
解决方案
要实现仅指定组用户可访问,需从Azure AD返回的Token中提取组信息,并在Node.js端完成校验,步骤如下:
1. 配置Azure AD在Token中返回组信息
- 登录Azure门户,进入Angular应用注册页,切换到令牌配置选项卡
- 添加可选声明:选择
groups,勾选对应令牌类型(ID令牌/访问令牌,根据业务需求选择) - 保存配置,确保用户登录时Token中包含
groups字段(存储组的Object ID)
2. 修改Node.js端BearerStrategy的校验逻辑
替换原bearerStrategy回调函数,添加组校验:
const bearerStrategy = new BearerStrategy(options, (token, done) => { // 替换为你的目标组Object ID,可在Azure AD组详情页获取 const allowedGroupId = "你的指定组ID"; const userGroups = token.groups || []; // 校验用户是否属于允许的组 if (!userGroups.includes(allowedGroupId)) { return done(null, false, { message: "用户不在允许的组内" }); } const user = { id: token.oid, name: token.name }; return done(null, user, token); });
3. 优化配置文件提升安全性
修改azure.conf.json的settings部分:
"settings": { "validateIssuer": true, // 开启Issuer校验,避免非法Token "passReqToCallback": true, // 允许回调函数获取req对象,方便后续扩展 "loggingLevel": "info" }
4. 修复Angular端请求头问题
原代码手动清空了authorization头,会导致MSAL拦截器无法自动添加Bearer Token,修改为:
fetchPosts() { // MSAL拦截器会自动为受保护资源添加认证头,无需手动设置 this.http.get(`${this.baseurl}/api/v1/auth/knowledgebase`) .subscribe((posts:any)=>{ console.log(posts) this.posts=posts }) }
5. 验证Token组信息
可在bearerStrategy回调中添加console.log(token.groups),查看返回的组ID是否与目标组ID一致,确保校验逻辑生效。
内容的提问来源于stack exchange,提问作者the programmer
相关产品推荐
相关产品推荐

