【发布时间】:2019-03-14 15:57:44
【问题描述】:
我有一个 .NET Core 2.1 Web API 应用程序,我在其中设置了 Azure AD 以进行身份验证。对于我的授权,我使用了AuthorizationHandler,它根据用户名进行一些验证。我遇到的问题是User.Identity.Name 总是返回null,我不知道为什么。
这是我的Startup.cs,我在那里设置了身份验证和授权:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseCors("AllowAnyOrigin");
app.UseAuthentication();
app.UseMvc();
}
public void ConfigureServices(IServiceCollection services)
{
// Azure AD
services.AddAuthentication(
sharedOptions =>
{
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(
options =>
{
options.Authority = "https://login.microsoftonline.com/" + "MyTenant";
options.Audience = "MyClientId";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = "https://login.microsoftonline.com/" + "MyTenant" +"/v2.0";
};
});
services.AddAuthorization(
options =>
{
options.AddPolicy("MyPolicy", policy => policy.Requirements.Add(new NameRequirement());
});
services.AddSingleton<IAuthorizationHandler, NameRequirementHandler>();
services.AddCors(options =>
{
options.AddPolicy("AllowAnyOrigin",
builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
});
services.Configure<MvcOptions>(options => {
options.Filters.Add(new CorsAuthorizationFilterFactory("AllowAnyOrigin"));
});
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
在我的AuthorizationHandler 中,我想获取经过身份验证的用户的名称,以便对其进行一些验证。我可以在请求中看到不记名令牌,但是 User.Identity.Name 和所有声明都是 null。
public class NameRequirementHandler : AuthorizationHandler<NameRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, NameRequirement requirement)
{
var authorizationFilterContext = context.Resource as AuthorizationFilterContext;
if (authorizationFilterContext != null)
{
HttpContext httpContext = authorizationFilterContext.HttpContext;
string userName = httpContext.User.Identity.Name; // ALWAYS NULL
//Do some validation here with the user name value
}
context.Succeed(requirement);
return Task.CompletedTask;
}
}
目前我有一个非常简单的控制器,用于测试身份验证和授权:
[Authorize(Policy = "MyPolicy")]
public class ValuesController
{
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
}
为了从 Bearer 令牌填充用户信息,我遗漏了什么?为了添加更多上下文,我将其从 .NET Framework 移植过来,它可以在那里工作,但它使用 .NET Core 中不存在的扩展方法 UseWindowsAzureActiveDirectoryBearerAuthentication
这是 .NET Framework 中的样子
public void Configuration(IAppBuilder app)
{
var tokenValidation = new TokenValidationParameters
{
ValidAudience = "https://graph.windows.net/"
};
var authOptions = new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Tenant = "MyTenant",
TokenValidationParameters = tokenValidation,
MetadataAddress = ""
};
app.UseWindowsAzureActiveDirectoryBearerAuthentication(authOptions);
}
我已经看到发布的其他问题并阅读了许多文章,但仍然无法让它发挥作用。我的哪一部分配置有问题?
提前致谢。
更新
我最终找到了解决此问题的方法,但受众值设置不正确。我没有将观众的价值设置为令牌的“aud”价值。你可以去https://jwt.ms查看令牌的声明并确保设置了正确的受众。
【问题讨论】:
-
你是如何测试你的项目的?你在点击
NameRequirementHandler之前登录了吗?我使用内置 AAD 身份验证模板进行了测试,但未能重现您的问题。请根据AspNetCoreAAD查看如何重现您的问题。 -
我正在从一个调用控制器的角度应用程序中对其进行测试。使用用户 AD 帐户登录后,它会使用不记名令牌调用端点。感谢您提供示例应用程序。我试过了,它也对我有用,但是当我将它移到我的应用程序时它不起作用。可能是因为示例应用程序是一个 MVC Web 应用程序,而我的是一个支持 docker 的 Web API 微服务?
-
您能否与我们分享一个可以重现您的问题的演示?看是否和docker有关,建议去掉docker支持试试。
-
在初始化
TokenValidationParameters对象时尝试设置NameClaimType = JwtClaimTypes.Name和RoleClaimType = JwtClaimTypes.Role。另外阅读这篇文章Missing Claims in the ASP.NET Core 2 OpenID Connect Handler? -
@TaoZhou 在浏览器中调用端点时,我终于可以让它工作了。现在尝试从具有不同主机的不同应用程序调用端点时出现问题,它会产生错误:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://login.microsoftonline.com我在我的Startup.cs中设置了 CORS 以允许任何来源、任何标头和任何方法,所以不允许确定为什么会这样。
标签: c# asp.net-web-api asp.net-core .net-core azure-active-directory