.NET Core 2 - Web Api - Azure AD - пользователь имеет значение NULL - PullRequest
0 голосов
/ 09 октября 2018

У меня есть приложение .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, чтобы просмотреть утверждения токена и убедиться, что установлена ​​правильная аудитория.

1 Ответ

0 голосов
/ 10 октября 2018

Вам необходимо вызвать UseAuthentication в методе Configure, где у вас есть доступ к IApplicationBuilder.Это будет что-то вроде этого,

// 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, который включает возможности аутентификации.»

https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.authappbuilderextensions.useauthentication?view=aspnetcore-2.0

...