首页 > 解决方案 > IHttpContextAccessor 在 AspNetCore 5 API 控制器中返回空用户名声明

问题描述

我的 AspNetCore 5 Web 应用程序中有一些 Api 控制器,其中包含一些可供未经身份验证的用户使用的方法,其中一些仅对授权用户可用。

假设有一个所有用户都可以添加评论的 ReviewController,但是如果用户通过了身份验证,我们应该填写用户名字段。

让我们在TestController中说:

[Route("api/[controller]/[action]/")]
[ApiController]
public class TestController
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    public TestController(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    [HttpGet]
    public string TestA()
    {
        return _httpContextAccessor.HttpContext.User.Identity.Name;
    }

    [HttpGet]
    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    public string TestB()
    {
        return _httpContextAccessor.HttpContext.User.Identity.Name;
    }
}

两种方法之间的唯一区别是Authorize属性。

我使用以下设置在应用程序中设置JwtBearer身份验证。

配置服务:

    public override void ConfigureServices(IServiceCollection services)
    {
        var jwtConfig = new JwtConfig
        {
            Secret = "some secrets!",
            Audience = "http://localhost:5000",
            Expires = 600,
            Issuer = "http://localhost:5000"
        };

        services.AddAuthorization();

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(jwt =>
        {
            var key = Encoding.ASCII.GetBytes(jwtConfig.Secret);
            jwt.SaveToken = true;
            jwt.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true, 
                IssuerSigningKey = new SymmetricSecurityKey(key),
                ValidateIssuer = true,
                ValidateAudience = true,
                RequireExpirationTime = true,
                ValidateLifetime = true,
                SaveSigninToken = true,
                ValidAudience = jwtConfig.Audience,
                ValidIssuer = jwtConfig.Issuer
            };
        });

        services.AddHttpContextAccessor();

        services.AddMvcCore()
            .AddDataAnnotations()
            .AddApiExplorer()
            .AddFormatterMappings()
            .AddCors();
    }

并配置:

        public void Configure(IApplicationBuilder app)
        {          
            app.UseDefaultFiles();
            app.UseStaticFiles();
            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

当我调用TestB它时,它会返回登录的用户名。但是,当我调用它时,TestA它返回 null。

为什么IHttpContextAccessor没有加载用户声明以及如何IHttpContextAccessor在任何情况下访问用户名和用户声明?假设我在控制器以外的其他层中使用它。

标签: asp.net-coreasp.net-web-apijwtasp.net-identityasp.net-authorization

解决方案


推荐阅读