繁体   English   中英

ASP.Net Core 2.1/WebAPI 应用程序:“未找到 HTTP 404”使用 [授权] 调用 REST url

[英]ASP.Net Core 2.1/WebAPI app: "HTTP 404 not found" calling a REST url with [Authorize]

我正在学习有关 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工作正常。

问:我错过了什么?

问:更重要的是,什么是解决问题的好方法?

问:我应该提供哪些(如果有)附加信息?

先感谢您!


更新:

  1. 在调用http://localhost:5000/api/ManageCar ,我首先登录(成功)。

  2. 这是我在 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 的回应:

  1. 我有一个 REST API,使用 Asp.Net Core 2.1 + Web API 用 C# 编写。
  2. API 有一个“GET”方法, /api/ManageCar 如果我在没有 [Authorize] 的情况下调用,它会起作用。
  3. 我正在使用Asp.Net Core Identity “保护”API。 URL 是“/帐户/登录”。 它需要使用 POST(传递用户名和密码)。 这也有效。
  4. 如果我注解“ManageCar”与[授权],然后登录(成功),然后拿到/api/ManageCar ......它并不直接进入我的控制器为“/ API / ManageCar”。
  5. 相反,它转到“/Account/Login”(我已经登录,结果是 HTTP 200),然后重定向到“ https://localhost:44342/Account/Login?ReturnUrl=%2Fapi%2FManageCar ”/
  6. 应该能够为我的登录名做一个 POST,并为我的(现在已经过身份验证的)查询做一个 GET - 它应该“正常工作”。
  7. 不幸的是,我不知道 Asp.Net 在“幕后”做什么......我不知道是什么导致了问题,也不知道如何解决它。

更新

  1. 我仍然没有解决这个问题 - 我仍然使用[Authorize]获得 HTTP 404,并且它在没有[Authorize]

  2. 我的 AccountController 和 ManageCarController 都有相同的路径:分别是[Route("api/[controller]/[action])]' and [Route("api/[controller])]`。 我仍然可以成功登录,当我尝试阅读“汽车”列表时仍然收到 HTTP 404。

  3. 我在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?

如果我理解你的意思是正确的,问题可能来自两件事:

  1. 您试图在没有登录的情况下访问/api/ManageCar 属性[Authorize]表示:此控制器/操作在分配给之前需要登录。

这就是为什么它重定向到路径: /Account/Login?ReturnUrl=%2Fapi%2FManageCar

您可以检查路径,有两部分:

  • 第一部分是: /Account/Login 这是登录页面的网址。

  • 第二部分是: ?ReturnUrl=%2Fapi%2FManageCar 我们可以这样理解?ReturnUrl=/api/ManageCar因为%2F代表/ 该参数查询字符串表示:登录成功后,请求将重定向到/api/ManaCar

    1. 第二个问题可能是:在Get方法中,您通过使用[HttpGet]将其设置为 GET 方法。 这意味着只能通过使用 GET 方法分配此方法。 因此,如果您尝试发出 POST 请求,它将不起作用。

[HttpGet]
public IEnumerable<CarViewModel> Get()
{
    IEnumerable<CarViewModel> list =
        this.mapper.Map<IEnumerable<CarViewModel>>(this.dbContext.cars.AsEnumerable());
    return list;
}

如果你使用jquery,登录成功后,你可以尝试发出这样的GET请求:

$.get('/api/ManageCar').done(function (data) {
    console.log(data);
});

或者将[HttpGet]属性更改为[HttpPost]属性:

$.post('/api/ManageCar').done(function (data) {
    console.log(data);
});

我认为这是路由的问题,您能否验证您的路由。 你有没有注意到这两个控制器有两条路由,每一条 [Route("[controller]/[action]")] 和 [Route("api/[controller]")]。

如果您的路由正常,您应该检查您的身份验证机制。 您如何检查用户是否已通过身份验证以及如何重定向,因为如果您已经通过身份验证,则无需在每个 Api 方法中重定向到您的登录方法。

谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM