.NET 6独立模式Azure Function应用配置联合登录咨询
独立模式(Isolated Worker)的Azure Functions无法通过门户直接配置联合登录,需要手动集成Azure AD的JWT验证逻辑,以下是完整实现步骤:
1. Azure AD应用注册配置
- 在Azure AD中注册新应用,记录租户ID和客户端ID。
- 进入应用的「暴露API」页面,添加自定义范围(例如
api://<客户端ID>/access_as_user),设置范围可被管理员和用户同意。 - 若有前端应用调用该Function API,需在应用注册的「API权限」中添加上述自定义范围并授予管理员同意。
2. 项目依赖与代码配置
安装NuGet包
在项目中安装Microsoft.Identity.Web包以简化Azure AD令牌验证:
dotnet add package Microsoft.Identity.Web
修改Program.cs配置验证服务
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Azure.Functions.Worker; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; var host = new HostBuilder() .ConfigureFunctionsWorkerDefaults(builder => { // 添加自定义验证中间件 builder.UseMiddleware<JwtAuthenticationMiddleware>(); }) .ConfigureServices(services => { // 配置Azure AD JWT验证 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(options => { options.TokenValidationParameters = new() { ValidateIssuer = true, ValidIssuer = $"https://login.microsoftonline.com/{Environment.GetEnvironmentVariable("AZURE_AD_TENANT_ID")}/v2.0", ValidateAudience = true, ValidAudience = Environment.GetEnvironmentVariable("AZURE_AD_CLIENT_ID"), }; }, options => { options.Instance = "https://login.microsoftonline.com/"; options.TenantId = Environment.GetEnvironmentVariable("AZURE_AD_TENANT_ID"); options.ClientId = Environment.GetEnvironmentVariable("AZURE_AD_CLIENT_ID"); }); services.AddAuthorization(); }) .Build(); host.Run();
实现自定义验证中间件
创建JwtAuthenticationMiddleware.cs,用于拦截请求并验证令牌:
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Middleware; public class JwtAuthenticationMiddleware : IFunctionsWorkerMiddleware { public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next) { var req = await context.GetHttpRequestDataAsync(); if (req == null) { await next(context); return; } // 仅对AuthorizationLevel.User的触发器执行验证 if (context.FunctionDefinition.TriggerMetadata.TryGetValue("AuthorizationLevel", out var level) && level.ToString() == "User") { var authResult = await req.HttpContext.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme); if (!authResult.Succeeded) { req.HttpContext.Response.StatusCode = StatusCodes.Status401Unauthorized; await req.HttpContext.Response.WriteAsync("Unauthorized: Invalid or missing access token"); return; } // 将验证通过的用户信息存入上下文 context.Items["AuthenticatedUser"] = authResult.Principal; } await next(context); } }
编写受保护的Function端点
添加带有AuthorizationLevel.User和[Authorize]特性的触发器:
using Microsoft.AspNetCore.Authorization; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using System.Security.Claims; public class ProtectedApiFunction { [Function("ProtectedGet")] [Authorize] public HttpResponseData Run( [HttpTrigger(AuthorizationLevel.User, "get", Route = "user/info")] HttpRequestData req, FunctionContext context) { var user = context.Items["AuthenticatedUser"] as ClaimsPrincipal; var response = req.CreateResponse(System.Net.HttpStatusCode.OK); response.WriteString($"Welcome {user?.Identity?.Name}! Your user ID: {user?.FindFirst(ClaimTypes.NameIdentifier)?.Value}"); return response; } }
3. 应用配置
在local.settings.json(本地开发)或Azure Functions门户的「应用设置」中添加以下配置:
{ "Values": { "AZURE_AD_TENANT_ID": "你的租户ID", "AZURE_AD_CLIENT_ID": "你的应用注册客户端ID", "AzureWebJobsStorage": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated" } }
4. 验证功能
- 通过Azure AD获取针对你的API范围的访问令牌(可使用Postman OAuth 2.0流程或Azure CLI获取)。
- 调用Function端点,在请求头中携带
Authorization: Bearer <你的访问令牌>。 - 令牌合法时返回200响应,无令牌或令牌无效时返回401未授权。
内容的提问来源于stack exchange,提问作者zu1b
相关产品推荐
相关产品推荐

