Asp.net core IHttpContextAccessor在AspNetCore 5 API控制器中返回空用户名声明
在我的AspNetCore 5 web应用程序中,我有一些Api控制器,其中包含一些方法,未经身份验证的用户可以使用这些方法,其中一些方法仅适用于授权用户 假设有一个ReviewController,所有用户都可以添加该控制器,但如果用户经过身份验证,则应填写用户名字段 让我们假设在测试控制器中:Asp.net core IHttpContextAccessor在AspNetCore 5 API控制器中返回空用户名声明,asp.net-core,asp.net-web-api,jwt,asp.net-identity,asp.net-authorization,Asp.net Core,Asp.net Web Api,Jwt,Asp.net Identity,Asp.net Authorization,在我的AspNetCore 5 web应用程序中,我有一些Api控制器,其中包含一些方法,未经身份验证的用户可以使用这些方法,其中一些方法仅适用于授权用户 假设有一个ReviewController,所有用户都可以添加该控制器,但如果用户经过身份验证,则应填写用户名字段 让我们假设在测试控制器中: [Route("api/[controller]/[action]/")] [ApiController] public class TestController { pr
[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();
});
}
和配置:
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
的用户名和用户声明?假设我在控制器以外的其他层中使用它。在将[Authorize(authorizationschemes=JwtBearerDefaults.authorizationscheme)]
更改为[Authorize]
之后,您是否可以尝试调用TestB
当我调用TestB
时,您的话有冲突,如果您调用TestB
并返回401
,您怎么知道它返回登录的用户名(如您问题中所述)?实际上,我认为身份验证在这两种情况下都失败了(调用TestA
和TestB
)。但是TestB
具有authorized属性
,访问将短路并返回401
。现在问题可能更难了,您需要检查您的请求是否包含有效的凭据信息,可能需要调试到源代码中,这实际上取决于您的实际代码。@King Michal问我是否尝试将[Authorize(authorization(authorizationschemes=jwtbearderdefaults.authorizationscheme)]
更改为[Authorize]
是否在张贴的代码中,我回答了这个问题。这意味着发布的代码中的TestB
返回登录的用户名。不确定更改后会有什么不同,您的默认身份验证方案是JwtBearerDefaults.AuthenticationScheme
,因此仅使用[Authorize]
应该与[Authorize(AuthenticationSchemes=JwtBearerDefaults.AuthenticationScheme]相同
-我现在感到困惑。只有在不使用身份验证中间件的情况下(通过UseAuthentication
),它们才不同。