【问题标题】:.NET Core 2 - Web Api - Azure AD - User is NULL.NET Core 2 - Web Api - Azure AD - 用户为 NULL
【发布时间】: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.NameRoleClaimType = 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


【解决方案1】:

您需要在有权访问 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,从而启用身份验证功能。”

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

【讨论】:

  • 我确保在我的Configure() 方法中有app.UseAuthentication(),我将示例代码放在我的问题中。我仍然看到这个问题。
猜你喜欢
  • 2019-05-30
  • 1970-01-01
  • 2020-06-28
  • 2021-10-13
  • 1970-01-01
  • 2020-06-27
  • 2020-03-09
  • 2020-11-13
  • 1970-01-01
相关资源
最近更新 更多