如何让Auth0 OAuth流程在Swagger调用的JWT Token中返回email声明
如何让Auth0 OAuth流程返回的JWT包含email声明
问题背景
通过Swagger触发Auth0 OAuth认证后,返回的Bearer Token负载仅包含sub、iss等基础字段,缺少email声明,但Auth0 SDK返回的Token却包含user_id和email字段。
所用代码
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using Microsoft.TeamFoundation.WorkItemTracking.WebApi; using Microsoft.VisualStudio.Services.Common; using [...]; var builder = WebApplication.CreateBuilder(args); var config = new ConfigurationBuilder() .AddJsonFile("appsettings.json").Build() .GetSection("Settings").Get<Settings>(); builder.Services.AddControllers(); builder.Services .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Authority = config.Auth0.Domain; options.Audience = config.Auth0.Audiences.First(); options.MetadataAddress = $"https://{config.Auth0.Domain}/.well-known/openid-configuration"; options.TokenValidationParameters = new TokenValidationParameters { ValidAudiences = config.Auth0.Audiences, ValidateAudience = true, ValidateLifetime = true }; }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(options=> { options.SwaggerDoc("v1", new OpenApiInfo { Title = "Title", Version = "v1" }); options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2, Flows = new OpenApiOAuthFlows { Implicit = new OpenApiOAuthFlow { AuthorizationUrl = new Uri($"https://{config.Auth0.Domain}/authorize/?audience={config.Auth0.Audiences.First()}"), TokenUrl = new Uri($"https://{config.Auth0.Domain}/oauth/token"), RefreshUrl = new Uri($"https://{config.Auth0.Domain}/oauth/token"), } }, In = ParameterLocation.Header, }); ; var reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = JwtBearerDefaults.AuthenticationScheme }; options.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = reference }, new List<string>() } }); }); builder.Services.AddMvc().AddMvcOptions(options => { options.Filters.Add(new AuthorizeFilter()); }); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(options => { options.OAuthClientId(config.Auth0.ClientId); options.OAuthClientSecret(config.Auth0.ClientSecret); }); app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseAuthentication(); app.MapControllers(); app.Run();
当前返回的Token负载示例
{ "iss": "https://instance.us.auth0.com/", "sub": "auth0|1234..........1234", "aud": "https://instance.us.auth0.com/api/v2/", "iat": 1234...1234, "exp": 1234...1234, "azp": "1234.....1234", "scope": "" }
解决步骤
1. 添加OAuth权限范围请求
Auth0不会默认在Token中包含用户邮箱等信息,需要明确请求openid、email等OpenID Connect标准权限范围:
- 修改SwaggerGen中的
AuthorizationUrl,追加scope参数:
AuthorizationUrl = new Uri($"https://{config.Auth0.Domain}/authorize/?audience={config.Auth0.Audiences.First()}&scope=openid email profile")
- 在SwaggerUI配置中指定请求的权限范围:
options.OAuthScopes(new[] { "openid", "email", "profile" });
2. 检查Auth0应用配置
- 登录Auth0控制台,进入目标应用的应用设置页面,确保
OIDC Conformant选项已开启(该模式遵循OpenID Connect标准,保证Token包含标准声明)。 - 确认目标API(即代码中
audience指定的API)的权限配置,确保允许获取用户信息类的权限。
3. 自定义规则强制添加声明(可选)
如果上述步骤后仍未获取到email声明,可在Auth0控制台的规则页面添加自定义规则,将邮箱写入Token:
function addEmailToToken(user, context, callback) { context.idToken['email'] = user.email; context.accessToken['email'] = user.email; callback(null, user, context); }
4. 读取Token中的email声明
认证通过后,可在代码中直接从用户Claims读取邮箱:
var email = User.Claims.FirstOrDefault(c => c.Type == "email")?.Value;
内容的提问来源于stack exchange,提问作者jwrightmail
相关产品推荐
相关产品推荐

