Я работаю над учебным пособием "Здравствуй, мир!" На Asp.Net Core.Я использую 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> Инструменты разработчика> Сеть:
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
УТОЧНЕНИЕ ОТВЕТА Тана Нгуайна:
- У меня есть REST API, написанный наC # с использованием Asp.Net Core 2.1 + веб-API.
- В API есть метод "GET",
/api/ManageCar
.Если я звоню без [Авторизовать], это работает. - Я "защищаю" API с помощью Asp.Net Core Identity .URL-адрес «/ Аккаунт / Логин».Необходимо использовать POST (для передачи имени пользователя и пароля).Это тоже работает.
- Если я аннотирую «ManageCar» с помощью [Authorize], а затем авторизируюсь (успешно), то THEN GET
/api/ManageCar
... он НЕ перейдет непосредственно к моему контроллеру для"/api/ManageCar". - Вместо этого он переходит в" / Account / Login "(я уже вошел в систему, результат HTTP 200), затем перенаправляет на" https://localhost:44342/Account/Login?ReturnUrl=%2Fapi%2FManageCar"/
- I должен быть в состоянии сделать POST для моего логина и GET для моего (теперь аутентифицированного) запроса - он должен"просто работать".
- К сожалению, я не знаю, что делает Asp.Net "за кулисами" ... и я не знаю, что является причиной проблемы или как ее устранить.
ОБНОВЛЕНИЕ
Я все еще не решил проблему - я все еще получаю HTTP 404 с [Authorize]
, и он работает без [Authorize]
И мой AccountController, и ManageCarController имеют одинаковый путь: [Route("api/[controller]/[action])]' and
[Route ("api / [controller])]`, соответственно.Я все еще могу войти в систему успешно, я все еще получаю HTTP 404. Когда я пытаюсь прочитать список "Cars".
Я включил регистрацию "Trace" в моем 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?