c# - .NET Core 2 - Web Api - Azure AD - 用户为 NULL

标签 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)
{
   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 token ,但是 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;
    }
}

目前我有一个非常简单的 Controller ,我用它来测试身份验证和授权:

[Authorize(Policy = "MyPolicy")]
public class ValuesController
{
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "value1", "value2" };
    }
}

为了从不记名 token 中填充用户信息,我缺少什么?为了添加更多上下文,我将它从 .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);
}

我已经看到其他问题已发布并阅读了很多文章,但仍然无法使它起作用。我的配置的哪一部分是错误的?

提前致谢。

已更新

我最终找到了这个问题的解决方案,受众值(value)设置不正确。我没有设置 token 的“aud”值的受众值(value)。你可以去https://jwt.ms查看 token 的声明并确保设置了正确的受众。

最佳答案

您需要在您有权访问 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://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.authappbuilderextensions.useauthentication?view=aspnetcore-2.0

关于c# - .NET Core 2 - Web Api - Azure AD - 用户为 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52728364/

相关文章:

entity-framework - 使用 EF 和 WebAPI,如何返回 ViewModel 并支持 IQueryable/OData?

c# - 如何从 ASP.NET Core 3 属性路由中排除 Controller

c# - 对列表项使用标签帮助器验证

asp.net-core - 在 MVC6 中创建自定义模型绑定(bind)器的正确方法是什么?

c# - 在 Redis 中存储和使用配置文件的最佳方式?

c# - 将项目添加到 List<string> 属性

c# - 我如何在 c# 中使用键对字典进行排序---是否可以使用 LINQ?

c# - 使用转换方法覆盖类型中的虚方法

javascript - 使用来自 AngularJS 的 Web API JSON 响应 - 错误 : expected and array but got an object

c# - 区域不工作的 WebAPI 2 属性路由