英文:
ASP.NET Core 7 Web API - authorization failed. These requirements were not met: DenyAnonymousAuthorizationRequirement: Requires an authenticated user
问题
Startup.cs
:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = jwtSettings.Issuer,
ValidAudience = jwtSettings.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Key)),
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
};
});
app.UseMiddleware<ErrorHandlerMiddleware>();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(options =>
{
foreach (var description in provider.ApiVersionDescriptions)
{
options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
}
});
}
app.UseCors();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
Token generation:
string CreateToken()
{
var jwtSettings = configuration.GetSection(nameof(AppSettings.Jwt)).Get<AppSettings.Jwt>();
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Key));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Name, loginDto.Username)
};
var jwtSecurityToken = new JwtSecurityToken(
expires: DateTime.Now.AddMinutes(30),
claims: claims,
signingCredentials: credentials,
issuer: jwtSettings.Issuer,
audience: jwtSettings.Audience);
var jwt = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
return jwt;
}
Controller:
[ApiController]
[ApiVersion("1.0")]
[Route("api/[controller]")]
public class CustomerEnvironmentsController : ControllerBase
{
#region Fields
private readonly ICustomerEnvironmentsRepository customerEnvironmentsRepository;
private readonly IMapper mapper;
private readonly IDtoValidatorFactory apiValidatorFactory;
private readonly IHttpHeaderParser httpHeaderParser;
#endregion
#region Constructor
public CustomerEnvironmentsController(ICustomerEnvironmentsRepository customerEnvironmentsRepository, IMapper mapper, IDtoValidatorFactory apiValidatorFactory, IHttpHeaderParser httpHeaderParser)
{
this.customerEnvironmentsRepository = customerEnvironmentsRepository ?? throw new ArgumentNullException(nameof(customerEnvironmentsRepository));
this.mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
this.apiValidatorFactory = apiValidatorFactory ?? throw new ArgumentNullException(nameof(apiValidatorFactory));
this.httpHeaderParser = httpHeaderParser ?? throw new ArgumentNullException(nameof(httpHeaderParser));
}
#endregion
[Authorize]
[HttpGet]
public async Task<ActionResult<List<CustomerEnvironmentDto>>> GetCustomerEnvironments()
{
//Ommitted
}
}
I only want this for specific endpoints, so I've added [Authorize]
only on one endpoint. I've tried setting my token as auth in Swagger, and I've also tried manually sending my token from an external app with an Authorization header with the value bearer token. I just don't know what else to check.
英文:
Startup.cs
:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = jwtSettings.Issuer,
ValidAudience = jwtSettings.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Key)),
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
};
});
app.UseMiddleware<ErrorHandlerMiddleware>();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(options =>
{
foreach (var description in provider.ApiVersionDescriptions)
{
options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
}
});
}
app.UseCors();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
Token generation:
string CreateToken()
{
var jwtSettings = configuration.GetSection(nameof(AppSettings.Jwt)).Get<AppSettings.Jwt>();
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Key));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Name, loginDto.Username)
};
var jwtSecurityToken = new JwtSecurityToken(
expires: DateTime.Now.AddMinutes(30),
claims: claims,
signingCredentials: credentials,
issuer: jwtSettings.Issuer,
audience: jwtSettings.Audience);
var jwt = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
return jwt;
}
Controller:
[ApiController]
[ApiVersion("1.0")]
[Route("api/[controller]")]
public class CustomerEnvironmentsController : ControllerBase
{
#region Fields
private readonly ICustomerEnvironmentsRepository customerEnvironmentsRepository;
private readonly IMapper mapper;
private readonly IDtoValidatorFactory apiValidatorFactory;
private readonly IHttpHeaderParser httpHeaderParser;
#endregion
#region Constructor
public CustomerEnvironmentsController(ICustomerEnvironmentsRepository customerEnvironmentsRepository, IMapper mapper, IDtoValidatorFactory apiValidatorFactory, IHttpHeaderParser httpHeaderParser)
{
this.customerEnvironmentsRepository = customerEnvironmentsRepository ?? throw new ArgumentNullException(nameof(customerEnvironmentsRepository));
this.mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
this.apiValidatorFactory = apiValidatorFactory ?? throw new ArgumentNullException(nameof(apiValidatorFactory));
this.httpHeaderParser = httpHeaderParser ?? throw new ArgumentNullException(nameof(httpHeaderParser));
}
#endregion
[Authorize]
[HttpGet]
public async Task<ActionResult<List<CustomerEnvironmentDto>>> GetCustomerEnvironments()
{
//Ommitted
}
}
And I only want this for specific endpoints so I've added [Authorize]
only on one endpoint. I've tried setting my token as auth in swagger, and I've also tried manually sending my token from an external app with an Authorization header with value bearer token.
I just don't know what else to check.
答案1
得分: 1
添加 System.IdentityModel.Tokens.Jwt NuGet 包似乎解决了这个问题。这一定是个 bug,没有任何地方表明缺少这个包。没有错误,没有警告,什么都没有。如果需要的话,它应该是主要 jwt 包的依赖项。
感谢用户 bsebe 的 这个答案,最终我解决了这个问题。
英文:
Ok so apparently adding System.IdentityModel.Tokens.Jwt nuget package solved it. This has to be a bug, nothing anywhere indicates that this package is missing. No error, no warnings, no nothing. If its needed it should be a dependency for the main jwt package.
Thanks to this answer from user bsebe i finally solved it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论