Аутентификация ядра сети ASP — перенаправление обратно к целевому действию

#asp.net #asp.net-mvc #api

#asp.net #asp.net-mvc #API

Вопрос:

В ASP.NET В основном проекте Rest API я настроил пользовательскую аутентификацию и могу комментировать действия контроллера с помощью [Authorize] атрибута, который перенаправляет неавторизованные запросы обратно на мой AuthController:

 [Route("api/[controller]")]
[ApiController]
public class ResponseController : ControllerBase
{
    [Authorize]
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        return JsonConvert.SerializeObject(Repository.GetResponse(id), Formatting.Indented);
    }
}

[Route("api/[controller]")]
[ApiController]
public class MetaController : ControllerBase
{
    [Authorize]
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        return JsonConvert.SerializeObject(Repository.GetMeta(id), Formatting.Indented);
    }
}

[Route("api/[controller]")]
[ApiController]
public class AuthController : Controller
{
    UserManager _userManager;
    public AuthController(UserManager userManager)
    {
        _userManager = userManager;
    }
    [HttpGet]
    [HttpPost]
    public ActionResult<string> LogIn()
    {
        try
        {
            //authenticate
            var username = Request.Headers["username"];
            var password = Request.Headers["pass"];
            if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(password))
                throw new Exception("Authentication Exception: Missing Username or Password");

            Task.Run(async () => {
                await _userManager.SignInAsync(this.HttpContext, username, password);
            }).GetAwaiter().GetResult();

            return RedirectToAction("Search", "Home", null);
            //^^^ How to send back to intended action?^^^
        }
        catch (Exception ex)
        {
            return AuthError();
        }
    }
}
  

Это работает, за исключением того, как мне использовать RedirectToAction метод для возврата обратно к предполагаемому контроллеру ( MetaController или ResponseController , в данном случае)? (тот, у которого отмечен метод [Authorize] , который для начала ввел нас в этот контроллер аутентификации)

Ответ №1:

Вам нужно использовать параметр returnUrl, например, так:

 [HttpGet]
[HttpPost]
public async Task<IActionResult> LogIn(string returnUrl = null)
{
    try
    {
        //authenticate
        var username = Request.Headers["username"];
        var password = Request.Headers["pass"];
        if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(password))
            throw new Exception("Authentication Exception: Missing Username or Password");

        await _userManager.SignInAsync(this.HttpContext, username, password);
        if (Url.IsLocalUrl(returnUrl))
        {
            return Redirect(returnUrl);
        }

        return RedirectToAction("Search", "Home", null);
    }
    catch (Exception ex)
    {
        return BadRequest(new {error = "Authentication Failed"});
    }
}
  

Я также исправляю асинхронность / ожидание действия контроллера. Вам нужно использовать async Task<ActionResult> вместо вашего ActionResult<string>

Комментарии:

1. Отличный ответ и работает «из коробки», за исключением того, что мой метод authError() возвращает ActionResult<string> (строку ошибки в формате json). Как мне сохранить это, если возвращаемый тип входа (returnUrl) — ActionResult или Task<ActionResult>?

2. Можете ли вы предоставить AuthError метод?

3. Упрощено для краткости: ActionResult<string> AuthError() { return "{ "error": "Authentication Failed" }"; }

4. Я думаю, вы можете использовать, BadRequest(...) которые возвращают 400 http-кода или использовать Ok(...) с тем же объектом ошибки, если вам нужно повторно выполнить 200 http-кода. Я уже редактирую свой ответ.

Ответ №2:

Вместо перенаправления создайте свой собственный атрибут, наследуемый от AuthorizeAttribute и переопределите OnAuthorization метод. Таким образом, вам не нужно беспокоиться о перенаправлении.

Комментарии:

1. Можете ли вы предоставить пример метода переопределения OnAuthorization ?