使用ADAL Angular 6 Wrapper调用API时跳转至微软登录页问题
问题分析与解决方案
我之前也碰到过类似的情况,这大概率是ADAL Angular wrapper的自动请求拦截机制在起作用,结合你的代码和现象,我来拆解下原因和解决办法:
核心原因
ADAL默认会自动拦截所有HTTP请求,它会检查请求对应的资源有没有有效的访问令牌:
- 如果你用的令牌不是针对API资源的访问令牌(比如误用到了ID令牌)
- 或者ADAL配置里的
resource和API的Azure AD资源ID不匹配 - 又或者请求的URL没有在
protectedResourceMap中映射到正确的资源ID
ADAL就会认为当前没有可用的有效令牌,自动触发登录流程跳转到微软登录页去获取令牌。另外,你代码里直接用this.adal6Service.userInfo.token,这个值很可能是ID令牌(用来验证用户身份),而不是调用API需要的访问令牌,这也会导致ADAL触发登录。
具体解决步骤
1. 确保获取的是针对API的访问令牌
不要直接用userInfo.token,而是调用ADAL的acquireToken方法获取对应API的访问令牌,它会自动处理令牌的刷新和有效性检查:
// 替换成你的API资源ID(Azure AD中API应用的Application ID URI) const apiResourceId = 'https://foo.com/api'; this.adal6Service.acquireToken(apiResourceId).subscribe(accessToken => { const headers = new HttpHeaders() .set('Content-Type', 'application/json') .set('Authorization', `Bearer ${accessToken}`); this.http.get(`https://foo.azurewebsites.net/${this.url}`, { headers }) .pipe( map((r: any) => { const a = r['data'] as BIExplorerSettings; if (a) { this.BIExplorerSettings = a; this.alreadyFetchedSettings = true; } return a; }) ) .subscribe(); });
2. 配置ADAL的资源映射
在ADAL初始化配置中,把API的URL映射到对应的资源ID,这样ADAL会自动为该URL的请求添加正确的令牌,甚至不需要手动设置Authorization头:
const adalConfig = { tenant: 'your-tenant-id', clientId: 'your-frontend-app-client-id', resource: 'https://foo.com/api', // 这里填API的资源ID protectedResourceMap: [ ['https://foo.azurewebsites.net/', 'https://foo.com/api'] ] };
3. 验证令牌的有效性
可以用jwt.io解码你的令牌,检查两个关键字段:
aud(受众):必须是API的资源ID,而不是前端应用的client IDexp(过期时间):确保令牌还在有效期内
4. (可选)跳过ADAL的自动拦截
如果想完全手动控制令牌,不想让ADAL拦截这个请求,可以把API URL加入unprotectedResources数组:
const adalConfig = { // 其他配置... unprotectedResources: ['https://foo.azurewebsites.net/'] };
这样ADAL就不会处理这个请求,你可以自己手动添加令牌,但要自己负责令牌的刷新和有效性检查。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

