C# .NET Core 2-Web Api-Azure AD-用户为空

C# .NET Core 2-Web Api-Azure AD-用户为空,c#,asp.net-web-api,asp.net-core,.net-core,azure-active-directory,C#,Asp.net Web Api,Asp.net Core,.net Core,Azure Active Directory,我有一个.NET Core 2.1 Web API应用程序,其中我设置了Azure AD进行身份验证。对于我的授权,我使用了一个AuthorizationHandler,它根据用户名进行一些验证。我遇到的问题是,User.Identity.Name总是返回null,我不知道为什么 这是我的Startup.cs,我在这里设置了身份验证和授权: public void Configure(IApplicationBuilder app, IHostingEnvironment env) { i

我有一个.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);
}
目前,我有一个非常简单的控制器,用于测试身份验证和授权:

[Authorize(Policy = "MyPolicy")]
public class ValuesController
{
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "value1", "value2" };
    }
}
我已经看到了其他的问题,并阅读了许多文章,但仍然无法使这项工作。我的配置的哪一部分是错误的

提前谢谢

已更新


我最终找到了这个问题的解决方案,受众价值设置不正确。我并没有设置观众的价值,即代币的“aud”价值。您可以转到查看令牌的声明,并确保设置了正确的访问群体。

您需要在有权访问IApplicationBuilder的配置方法中调用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添加到指定的IAApplicationBuilder,从而启用身份验证功能。”


您是如何测试您的项目的?在点击
NameRequirementHandler
之前您是否登录过?我用内置的AAD认证模板做了一个测试,但无法重现您的问题。请检查如何基于复制您的问题。我正在从调用控制器的角度应用程序进行测试。在使用用户AD帐户登录后,它使用承载令牌调用端点。感谢您提供的示例应用程序。我尝试过它,它对我也很有效,但是当我将它移动到我的应用程序时,它不起作用。可能是因为示例应用程序是一个MVC web应用程序,而我的是一个具有docker支持的web API微服务吗?您能否与我们分享一个演示,重现您的问题?要检查它是否与docker相关,我建议您删除docker支持以进行尝试。在初始化
TokenValidationParameters
对象时,尝试设置
NameClaimType=JwtClaimTypes.Name
RoleClaimType=JwtClaimTypes.Role
。另外,当在浏览器中调用端点时,我终于能够在@TaoZhou阅读这篇文章。现在,当尝试从具有不同主机的不同应用程序调用端点时出现问题,它会产生错误:
跨源请求被阻止:同一源策略不允许读取远程资源https://login.microsoftonline.com
我在我的
Startup.cs中设置了COR,以允许任何来源,任何标题和任何方法,因此不确定发生这种情况的原因。我确保在我的
Configure()
方法中有
app.UseAuthentication()
,我将示例代码放入了我的问题中。我仍然看到这个问题。
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);
}
// 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();
}