OpenId Connect + .NET 8独立模式:如何在Azure Function中实现OIDC?
OpenId Connect与Azure Function + .NET 8独立模式集成最佳实践
核心实现步骤
- 步骤1:配置Azure AD应用注册
在Azure门户创建应用注册,记录客户端ID、租户ID、客户端密钥(或证书)。设置重定向URI为函数的登录回调地址,本地调试可用http://localhost:7071/.auth/login/aad/callback,部署到Azure后使用https://<your-function-app>.azurewebsites.net/.auth/login/aad/callback。 - 步骤2:添加NuGet包依赖
在.NET 8独立模式函数项目中安装以下包:Microsoft.Azure.Functions.Worker.Extensions.Http Microsoft.Identity.Web Microsoft.Azure.Functions.Worker - 步骤3:配置应用设置
在local.settings.json(本地调试)或Azure函数应用配置中添加:{ "AzureAd:ClientId": "<你的客户端ID>", "AzureAd:TenantId": "<你的租户ID>", "AzureAd:ClientSecret": "<你的客户端密钥>", "AzureAd:Instance": "https://login.microsoftonline.com/", "AzureAd:Domain": "<你的租户域名>" } - 步骤4:配置函数启动类
在Program.cs中注册Identity Web服务:var host = new HostBuilder() .ConfigureFunctionsWebApplication() .ConfigureServices(services => { services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd")); services.AddAuthorization(); }) .Build(); host.Run(); - 步骤5:保护函数端点
在函数方法上添加[Authorize]特性,指定认证方案:[Function("ProtectedFunction")] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] public IActionResult Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req, ClaimsPrincipal principal) { return new OkObjectResult($"Hello {principal.Identity.Name}!"); }
关键注意事项
- 独立模式适配:.NET 8独立模式基于
FunctionsWorker运行,需使用最新版Microsoft.Identity.Web,它已适配该模式的运行环境。 - 令牌自动验证:
AddMicrosoftIdentityWebApi默认会验证ID令牌的签名、有效期、受众等核心要素,无需手动编写验证逻辑。 - 本地调试配置:确保
local.settings.json中的参数与Azure AD应用注册一致,且回调URI已在应用注册中完成配置。 - 权限配置:根据业务需求为应用注册添加对应API权限(如Microsoft Graph),并完成管理员同意操作。
自定义扩展示例
- 若需添加自定义令牌验证逻辑,可通过
ConfigureJwtBearerOptions扩展:services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd")) .ConfigureJwtBearerOptions(options => { options.Events = new JwtBearerEvents { OnTokenValidated = context => { // 示例:检查用户是否包含特定角色声明 var hasRequiredRole = context.Principal.HasClaim(c => c.Type == ClaimTypes.Role && c.Value == "Admin"); if (!hasRequiredRole) { context.Fail("用户无访问权限"); } return Task.CompletedTask; } }; }); - 从
ClaimsPrincipal中提取用户核心信息:var userId = principal.FindFirst(ClaimTypes.NameIdentifier)?.Value; var email = principal.FindFirst(ClaimTypes.Email)?.Value; var userName = principal.Identity.Name;
需求满足核心要点
- 安全性:严格遵循OpenId Connect规范验证令牌,仅授权用户可访问受保护端点。
- 可维护性:通过配置文件管理认证参数,避免硬编码,便于后续环境切换与参数修改。
- 兼容性:适配Azure函数独立模式运行时,确保本地调试与云端部署行为一致。
内容的提问来源于stack exchange,提问作者Luan Souza - Dev LuanS0
相关产品推荐
相关产品推荐

