我有一个.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
中,我想获取经过身份验证的用户的名称,以便对其进行验证。我可以在请求中看到Bearer令牌,但是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查看令牌的声明,并确保设置了正确的受众。
答案 0 :(得分:0)
您需要在可访问IApplicationBuilder的Configure方法中调用UseAuthentication。会是这样,
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseAuthentication(); // Make sure you've done this!
app.UseMvc();
}
从文档中,“将AuthenticationMiddleware添加到指定的IApplicationBuilder,从而启用身份验证功能。”