[英]Why don't my unauthorized controllers return 401 ASP.Net Core?
I'm using Visual studio code and I'm using dot net core framework for a RestAPI.我正在使用 Visual Studio 代码,并且正在为 RestAPI 使用 dot net core 框架。 When I access do a controller with "Authorize" attribute, it should return a 401 request but it doesn't return anything in postman.
当我访问带有“授权”属性的控制器时,它应该返回一个 401 请求,但它不会在邮递员中返回任何内容。 Just a blank.
只是一片空白。
I think it should comes from my startup code.我认为它应该来自我的启动代码。
I'll share you my configure method in startup file.我将在启动文件中与您分享我的配置方法。
Best thanks for your help.非常感谢您的帮助。 If you can find a solution on internet, just share it (I already look for but... Maybe I didn't type the right keyword.)
如果您可以在互联网上找到解决方案,只需分享它(我已经在寻找但是...也许我没有输入正确的关键字。)
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration;公共类启动 { 公共启动(IConfiguration 配置){ 配置 = 配置; }
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
ConfigureContext(services);
services.AddCors();
services.AddAutoMapper(typeof(Startup));
// configure strongly typed settings objects
var appSettingsSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
// configure jwt authentication
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
var userService = context.HttpContext.RequestServices.GetRequiredService<IUserService>();
var userId = int.Parse(context.Principal.Identity.Name);
var user = userService.GetById(userId);
if (user == null)
{
// return unauthorized if user no longer exists
context.Fail("Unauthorized");
}
return Task.CompletedTask;
}
};
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "dotnetcore-api-core",
Version = "v1"
});
});
services.AddScoped<IUserService, UserService>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
app.UseMvc();
app.UseStaticFiles();
app.UseHttpsRedirection();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Security JWT
app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "dotnetcore-api-core V1");
});
}
public void ConfigureContext(IServiceCollection services)
{
// Database injection
services.AddDbContext<UserContext>(options =>
options.UseMySql(Configuration.GetConnectionString("AppDatabase")));
}
}
My controller that doesn't return 401 unauthorized:我的控制器未返回 401 未经授权:
[Authorize]
[Route("api/users")]
[ApiController]
public class UserController : ControllerBase
{
private readonly IUserService _userService;
private IMapper _mapper;
public UserController(
IUserService userService,
IMapper mapper)
{
_userService = userService;
_mapper = mapper;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<User>>> GetUsers()
{
IEnumerable<User> users = await _userService.GetAll();
if(users == null)
{
return NotFound();
}
return Ok(users);
}
I followed this tutorial -> https://jasonwatmore.com/post/2018/08/14/aspnet-core-21-jwt-authentication-tutorial-with-example-api我遵循了本教程-> https://jasonwatmore.com/post/2018/08/14/aspnet-core-21-jwt-authentication-tutorial-with-example-api
An example image in postman : Image example of empty body postman邮递员中的示例图像:空身体邮递员的图像示例
I think your problem is the same.我想你的问题是一样的。 You can add a few lines of code as below (in the Startup.cs file):
您可以添加如下几行代码(在 Startup.cs 文件中):
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors(pol => pol.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.UseAuthentication();
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseStatusCodePages(async context =>
{
if (context.HttpContext.Request.Path.StartsWithSegments("/api"))
{
if (!context.HttpContext.Response.ContentLength.HasValue || context.HttpContext.Response.ContentLength == 0)
{
// You can change ContentType as json serialize
context.HttpContext.Response.ContentType = "text/plain";
await context.HttpContext.Response.WriteAsync($"Status Code: {context.HttpContext.Response.StatusCode}");
}
}
else
{
// You can ignore redirect
context.HttpContext.Response.Redirect($"/error?code={context.HttpContext.Response.StatusCode}");
}
});
app.UseMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseExceptionHandler("/api/errors/500");
app.UseStatusCodePagesWithReExecute("/api/errors/{0}");
// or app.UseStatusCodePagesWithRedirects("~/api/errors/{0}");
app.UseRouting();
...
}
Then, create ErrorController like:然后,创建 ErrorController 像:
[ApiController]
[Route("api/errors")]
public class ErrorController : Controller
{
[HttpGet("{code}")]
public async Task<IActionResult> Get(int code)
{
return await Task.Run(() =>
{
return StatusCode(code, new ProblemDetails()
{
Detail = "See the errors property for details.",
Instance = HttpContext.Request.Path,
Status = code,
Title = ((HttpStatusCode)code).ToString(),
Type = "https://my.api.com/response"
});
});
}
}
I hope this helps.我希望这有帮助。
Try to move this line to the top of the Configure method:尝试将此行移动到Configure方法的顶部:
app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
Eg:例如:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.UseAuthentication();
app.UseMvc();
// the rest of you code here
}
Your call is returning 401. It is clearly visible in the postman.你的电话是返回 401。它在邮递员身上清晰可见。 Body is ofcourse empty, but if you look a little bit higher and on the right site (in the same line that it is body, cookies, headers tab), you will see Status line that will say 401 Unauthorised.
正文当然是空的,但是如果您在正确的站点(与正文、cookie、标题选项卡在同一行中)看高一点,您将看到状态行,其中显示 401 未经授权。 It also shows you how much time did it take for this response and what is the size of the response.
它还向您显示此响应花费了多少时间以及响应的大小。
Add route to your GetUsers action :将路由添加到您的 GetUsers 操作:
[Route("GetUsers")]
public async Task<ActionResult<IEnumerable<User>>> GetUsers()
And call it in Postman like this ...api/Users/GetUsers并像这样在 Postman 中调用它...api/Users/GetUsers
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.