Azure Functions(.NET8独立模式)OIDC请求Header中Access Token验证咨询
.NET 8 Azure Functions JWT 验证实现方案
推荐方案:使用内置认证中间件(基于Microsoft.Identity.Web)
这种方式无需自定义中间件,借助官方包即可快速实现OpenID Connect兼容的JWT验证,自动处理JWKS获取、签名校验、受众/发行人验证等逻辑。
步骤1:安装依赖包
通过NuGet安装以下包:
Microsoft.Azure.Functions.Worker.Extensions.Http Microsoft.Identity.Web Microsoft.Azure.Functions.Worker
步骤2:配置认证参数
在appsettings.json中添加OIDC提供商(以Azure AD为例)的配置:
{ "AzureAd": { "Instance": "https://login.microsoftonline.com/", "TenantId": "你的租户ID", "ClientId": "你的应用ID" }, "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated" }
步骤3:配置服务与中间件
在Program.cs中注册认证和授权服务:
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Azure.Functions.Worker; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Identity.Web; var host = new HostBuilder() .ConfigureFunctionsWebApplication() .ConfigureServices(services => { // 注册JWT认证服务,绑定OIDC配置 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd")); // 启用授权 services.AddAuthorization(); }) .Build(); host.Run();
步骤4:保护你的函数
在Get函数上添加[Authorize]特性,同时将HttpTrigger的授权级别设为Anonymous(避免Azure Functions内置密钥验证冲突):
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.Functions.Worker; using Microsoft.Extensions.Logging; namespace YourFunctionNamespace; public class ProtectedRouteFunction { private readonly ILogger<ProtectedRouteFunction> _logger; public ProtectedRouteFunction(ILogger<ProtectedRouteFunction> logger) { _logger = logger; } [Function("ProtectedRoute")] [Authorize] public IActionResult Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req) { _logger.LogInformation("处理受保护的请求"); return new OkObjectResult("Protected Route, 200"); } }
自定义授权策略(可选)
如果需要验证特定Claim(比如权限范围),可以添加自定义策略:
// 在Program.cs的ConfigureServices中 services.AddAuthorization(options => { options.AddPolicy("RequireAccessScope", policy => { policy.RequireAuthenticatedUser(); policy.RequireClaim("scope", "api://你的应用ID/access_as_user"); }); }); // 函数上使用自定义策略 [Authorize(Policy = "RequireAccessScope")]
自定义中间件方案(若需完全自定义验证逻辑)
如果一定要手动实现JWT验证中间件,可参考以下代码:
自定义中间件类
using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Protocols; using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Tokens; public class JwtValidationMiddleware { private readonly RequestDelegate _next; private readonly IConfiguration _configuration; private readonly ILogger<JwtValidationMiddleware> _logger; private readonly IConfigurationManager<OpenIdConnectConfiguration> _configManager; public JwtValidationMiddleware(RequestDelegate next, IConfiguration configuration, ILogger<JwtValidationMiddleware> logger) { _next = next; _configuration = configuration; _logger = logger; // 初始化OIDC配置管理器,自动获取JWKS var metadataAddress = $"{_configuration["AzureAd:Instance"]}{_configuration["AzureAd:TenantId"]}/v2.0/.well-known/openid-configuration"; _configManager = new ConfigurationManager<OpenIdConnectConfiguration>( metadataAddress, new OpenIdConnectConfigurationRetriever(), new HttpDocumentRetriever()); } public async Task InvokeAsync(HttpContext context) { // 检查Authorization Header if (!context.Request.Headers.TryGetValue("Authorization", out var authHeader)) { context.Response.StatusCode = StatusCodes.Status401Unauthorized; await context.Response.WriteAsync("缺少Authorization请求头"); return; } var token = authHeader.ToString().Replace("Bearer ", string.Empty); try { // 获取最新的OIDC配置(含JWKS) var oidcConfig = await _configManager.GetConfigurationAsync(CancellationToken.None); var validationParams = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = oidcConfig.Issuer, ValidateAudience = true, ValidAudience = _configuration["AzureAd:ClientId"], ValidateLifetime = true, IssuerSigningKeys = oidcConfig.SigningKeys }; // 验证Token var handler = new JwtSecurityTokenHandler(); handler.ValidateToken(token, validationParams, out var validatedToken); // 将验证后的Claims绑定到HttpContext context.User = new ClaimsPrincipal(new ClaimsIdentity(((JwtSecurityToken)validatedToken).Claims, "JWT")); // 继续处理请求 await _next(context); } catch (SecurityTokenException ex) { _logger.LogError(ex, "JWT验证失败"); context.Response.StatusCode = StatusCodes.Status401Unauthorized; await context.Response.WriteAsync($"无效Token: {ex.Message}"); } } }
注册中间件
在Program.cs中添加中间件注册:
var host = new HostBuilder() .ConfigureFunctionsWebApplication(app => { // 注册自定义JWT验证中间件 app.UseMiddleware<JwtValidationMiddleware>(); }) .ConfigureServices(services => { // 其他服务配置 }) .Build(); host.Run();
内容的提问来源于stack exchange,提问作者Luan Souza - Dev LuanS0
相关产品推荐
相关产品推荐

