У меня есть приложение .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);
}
В моем my 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" };
}
}
Чего мне не хватает, чтобы заполнить информацию пользователя из токена на предъявителя?Чтобы добавить немного контекста, я портирую это из .NET Framework, и он работает там, но использует метод расширения UseWindowsAzureActiveDirectoryBearerAuthentication
, которого нет в .NET Core
Вот как это выглядитв .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, чтобы просмотреть утверждения токена и убедиться, что установлена правильная аудитория.