【发布时间】:2019-04-22 10:04:19
【问题描述】:
我正在学习有关 Asp.Net Core 的“hello world”教程。我正在使用 WebApi(不是 MVC)。
这是我尝试调用的 REST API 的控制器:
...
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ManageCarController : ControllerBase
{
private IMapper mapper;
private ApplicationDbContext dbContext;
public ManageCarController(IMapper mapper, ApplicationDbContext dbContext)
{
this.mapper = mapper;
this.dbContext = dbContext;
}
// GET api/values
[HttpGet]
public IEnumerable<CarViewModel> Get()
{
IEnumerable<CarViewModel> list =
this.mapper.Map<IEnumerable<CarViewModel>>(this.dbContext.cars.AsEnumerable());
return list;
}
...
这是我的登录控制器:
...
[Authorize]
[Route("[controller]/[action]")]
public class AccountController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly ILogger _logger;
public AccountController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
ILogger<AccountController> logger)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
}
[TempData]
public string ErrorMessage { get; set; }
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Login([FromBody]LoginViewModel model)
{
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync
(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
var msg = "User logged in.";
return Ok(msg);
}
}
// If we got this far, something failed, redisplay form
return BadRequest("Fail to login with this account");
}
我可以登录 (http://localhost:5000/Login) 好的,响应是“用户登录”。
当我浏览到 http://localhost:5000/api/ManageCar 时,它会重定向到这里并给我一个 HTTP 404:https://localhost:44342/Account/Login?ReturnUrl=%2Fapi%2FManageCar,而我从未点击过控制器。
如果我注释掉[Authorize],那么http://localhost:5000/api/ManageCar 可以正常工作。
问:我错过了什么?
问:更重要的是,解决问题的好方法是什么?
问:我应该提供哪些(如果有)额外信息?
提前谢谢你!
更新:
在调用
http://localhost:5000/api/ManageCar之前,我先登录(成功)。-
这是我在 Edge > Developer Tools > Network 中看到的:
Name Protocol Method Result Content type Received Time Initiator https://localhost:44342/Account/Login HTTP/2 POST 200 application/json 9.31 s XMLHttpRequest <= Login: OK https://localhost:44342/Account/Login HTTPS GET 200 (from cache) 0 s <= ManageCars (GET@1): OK https://localhost:44342/api/ManageCar HTTP/2 GET 302 0 B 97.43 ms XMLHttpRequest <= ManageCars (GET@2 - 302 redirect to REST API): OK https://localhost:44342/Account/Login?ReturnUrl=%2Fapi%2FManageCar HTTP/2 GET 404 0 B 16.77 ms XMLHttpRequest <= ManageCars (GET@3 - 404: not found): FAILS - Console: HTTP 404: NOT FOUND - The server has not found anything matching the requested URI (Uniform Resource Identifier). (XHR)GET - https://localhost:44342/Account/Login?ReturnUrl=%2Fapi%2FManageCar
澄清 Tân Nguyễn 的回应:
- 我有一个 REST API,使用 Asp.Net Core 2.1 + Web API 用 C# 编写。
- API 有一个“GET”方法,
/api/ManageCar。如果我在没有 [Authorize] 的情况下调用,它会起作用。 - 我正在使用Asp.Net Core Identity“保护”API。 URL 是“/帐户/登录”。它需要使用 POST(传递用户名和密码)。这也有效。
- 如果我用 [Authorize] 注释“ManageCar”,然后登录(成功),然后 THEN GET
/api/ManageCar... 它不会直接转到我的控制器以获取“/ api/ManageCar”。 - 相反,它转到“/Account/Login”(我已经登录,结果是 HTTP 200),然后重定向到“https://localhost:44342/Account/Login?ReturnUrl=%2Fapi%2FManageCar”/
- 我应该能够为我的登录做一个 POST,并为我的(现已通过身份验证的)查询做一个 GET - 它应该“正常工作”。
- 不幸的是,我不知道 Asp.Net 在“幕后”做了什么......我不知道是什么导致了问题,也不知道如何解决它。
更新
我仍然没有解决问题 - 我仍然收到带有
[Authorize]的 HTTP 404,并且它在没有[Authorize]的情况下也能正常工作我的 AccountController 和 ManageCarController 都有相同的路径:
[Route("api/[controller]/[action])]' and[Route("api/[controller])]`,分别。我仍然可以成功登录,当我尝试时仍然得到 HTTP 404阅读“汽车”列表。-
我在
appsettings.json中启用了“跟踪”日志记录。以下是失败的 API 调用的输出摘要:Console log: - Request starting HTTP/1.1 GET http://localhost:63264/api/ManageCar Request finished in 81.994ms 302 - Request starting HTTP/1.1 GET http://localhost:63264/Account/Login?ReturnUrl=%2Fapi%2FManageCar AuthenticationScheme: Identity.Application was successfully authenticated. The request path /Account/Login does not match a supported file type The request path does not match the path filter Request finished in 31.9471ms 404 SUMMARY: a) request to "ManageCar" redirects to AccountController => OK b) AccountController gets the request => OK c) Q: Does AccountController authenticate the request? <= it *seems* to ("successfully authenticated"...) d) Q: What do "match a supported file type" or "match the path filter" mean? What can I do about them?
【问题讨论】:
-
您的登录方法只接受 HTTP
POST,但重定向将是GET请求。 -
@DavidG:我在调用 API 之前使用 POST 成功登录。我正在使用从 Edge > Developer Tools 获得的网络调用来更新我的帖子。
-
问:如果我只需要一个
[HttpGet](我是 Asp.Net Core 的新手——不要相信你),那我该怎么做呢?你能给我一个“回应”,指出我正确的方向吗? -
尝试通过将属性更改为
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]来指定身份验证模式。您正在尝试使用 cookie 授权 web api,如果没有其他配置,它可能会失败 -
一般情况下,PasswordSignInAsync 用于 cookie 认证,如果你只有 web api,可能需要移动到 JWT 令牌
标签: c# asp.net-core asp.net-web-api2 identity