Dotnet-Isolated Azure Functions如何实现等效HttpContext.ValidateAppRole的校验
Dotnet Isolated模式Azure Function 等效ValidateAppRole的实现方案
前置依赖
你需要先安装以下NuGet包:
Microsoft.IdentityModel.Protocols.OpenIdConnectSystem.IdentityModel.Tokens.JwtMicrosoft.IdentityModel.Tokens
核心实现逻辑
我们可以直接从HttpRequestData中提取令牌、完成校验和角色匹配,不需要依赖HttpContext,具体步骤如下:
- 从请求头提取Authorization字段,去除
Bearer前缀拿到原始Access Token - 配置匹配你Azure AD应用的JWT校验参数,包括租户ID、受众(即目标函数对应的Azure AD应用客户端ID)、颁发者等
- 完成令牌有效性校验
- 从校验通过后的Claims集合中匹配
roles声明,判断是否包含指定的自定义角色
完整代码示例
首先封装一个通用的校验扩展方法:
using Microsoft.Azure.Functions.Worker.Http; using Microsoft.IdentityModel.Protocols; using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; public static class HttpRequestDataAuthExtensions { // 替换为你自己的Azure AD配置,建议放在配置文件中读取 private const string TenantId = "你的Azure AD租户ID"; private const string Audience = "目标函数对应的Azure AD应用客户端ID"; private static readonly string Issuer = $"https://sts.windows.net/{TenantId}/"; // 缓存OpenId配置,避免每次请求重复拉取 private static readonly ConfigurationManager<OpenIdConnectConfiguration> _configManager = new ConfigurationManager<OpenIdConnectConfiguration>( $"https://login.microsoftonline.com/{TenantId}/.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever()); public static bool ValidateAppRole(this HttpRequestData req, string requiredRole) { // 1. 提取令牌 if (!req.Headers.TryGetValues("Authorization", out var authHeaders) || authHeaders.FirstOrDefault()?.StartsWith("Bearer ") != true) { return false; } var accessToken = authHeaders.First().Substring("Bearer ".Length).Trim(); // 2. 配置校验参数 var validationParameters = new TokenValidationParameters { ValidAudience = Audience, ValidIssuer = Issuer, ValidateIssuerSigningKey = true, ValidateLifetime = true, ClockSkew = TimeSpan.FromMinutes(5) }; try { // 加载签名公钥 var openIdConfig = _configManager.GetConfigurationAsync(CancellationToken.None).GetAwaiter().GetResult(); validationParameters.IssuerSigningKeys = openIdConfig.SigningKeys; // 3. 校验令牌有效性 var tokenHandler = new JwtSecurityTokenHandler(); ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(accessToken, validationParameters, out _); // 4. 匹配自定义角色 return claimsPrincipal.HasClaim(c => c.Type == "roles" && c.Value == requiredRole); } catch (SecurityTokenException) { // 令牌无效、过期、签名错误等情况都返回校验失败 return false; } } }
然后在你的Azure Function中直接调用即可,和原HttpContext.ValidateAppRole用法完全一致:
[Function("YourTargetFunction")] public HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req) { // 校验自定义角色 if (!req.ValidateAppRole("CustomRoleName")) { var forbiddenRes = req.CreateResponse(System.Net.HttpStatusCode.Forbidden); return forbiddenRes; } // 正常业务逻辑 var response = req.CreateResponse(System.Net.HttpStatusCode.OK); response.WriteString("权限校验通过"); return response; }
注意事项
- 所有Azure AD相关配置建议不要硬编码,通过
IConfiguration从应用配置/环境变量中读取 - 如果你的令牌中角色声明的Type不是
roles,可以把HasClaim方法中的Type替换为实际的声明类型,比如http://schemas.microsoft.com/ws/2008/06/identity/claims/role
内容的提问来源于stack exchange,提问作者Rob Bowman
相关产品推荐
相关产品推荐

