从Angular-cli应用在Azure Function(C#)中获取用户信息遇阻
解决Azure Function中无法通过前端ADAL令牌获取用户信息的问题
我之前在做Angular+Azure Function的项目时,也碰到过几乎一模一样的问题——用adal-angular5登录后,调用Http触发器就是拿不到用户信息。结合我的踩坑经验,给你整理了一套可行的解决方案:
1. 先确保前端正确传递令牌到Function
用adal-angular5的话,最稳妥的方式是写个Http拦截器,自动给所有请求加上Authorization头,格式是Bearer <token>。这样不用每次调用Function都手动加令牌,示例代码如下:
import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http'; import { AdalService } from 'adal-angular5'; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private adalService: AdalService) {} intercept(req: HttpRequest<any>, next: HttpHandler) { // 从ADAL缓存里拿到令牌 const token = this.adalService.getCachedToken(this.adalService.config.clientId); if (token) { // 克隆请求并添加Authorization头 const authReq = req.clone({ headers: req.headers.set('Authorization', `Bearer ${token}`) }); return next.handle(authReq); } return next.handle(req); } }
写完拦截器后,记得在你的Angular模块里注册它,不然不会生效哦。
2. 给Azure Function开启AD身份验证
Azure Function本身得知道要验证这个令牌,所以得在门户里配置AD认证:
- 打开Azure门户,找到你的Function App
- 左侧菜单找「Authentication」(旧版门户可能叫「App Service Authentication」)
- 点击「Add identity provider」,选Microsoft作为身份提供者
- 配置的时候,租户ID、客户端ID要和你Angular应用里的AD应用完全一致,然后把「未认证请求的处理动作」设为「返回HTTP 401 Unauthorized」
- 保存配置后,Function就会自动帮你验证令牌的有效性,不用自己写验证逻辑了
3. 在Function代码里直接拿用户信息
当令牌验证通过后,用户信息会自动注入到请求上下文里,直接用就行:
- 如果是C# Function:
public static async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log, ClaimsPrincipal principal) { // 从Claims里提取用户ID和用户名,其他信息按需取 var userId = principal.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value; var userName = principal.FindFirst(System.Security.Claims.ClaimTypes.Name)?.Value; return new OkObjectResult(new { UserId = userId, UserName = userName }); }
- 如果是Node.js Function:
module.exports = async function (context, req) { // 用户信息存在context.request.user里 const userId = context.request.user.sub; const userName = context.request.user.name; context.res = { body: { userId: userId, userName: userName } }; };
这里要注意,AuthorizationLevel要设为Anonymous,因为我们靠AD认证来控制访问,不是Function的密钥。
4. 排查令牌有效性的小技巧
如果还是拿不到信息,先排查令牌本身:
- 用Chrome DevTools看请求头里有没有正确带Authorization,令牌有没有写错
- 把令牌复制到
jwt.ms(微软的官方解码工具,安全可靠)里解码,看看里面的Claims全不全,令牌有没有过期,还有受众(aud)是不是和Function的AD应用客户端ID一致
另外,adal-angular5默认拿的是id_token,如果你需要更细粒度的权限,也可以尝试获取access_token,记得确保access_token的受众是Function的客户端ID哦。
内容的提问来源于stack exchange,提问作者RubenHerman
相关产品推荐
相关产品推荐

