Подтвердить что ты не робот

Создать ссылку Reset Пароль в WebApi

Я хотел создать ссылку для пароля reset для отправки пользователю электронной почты, который откроет страницу ResetPassword. На этой странице я напишу подробности о новом пароле и подтвердите пароль.

Для этого я последовал за этой ссылкой

Но есть метод Url.Action, который я не могу найти в своем веб-проекте api.

var callbackUrl = Url.Action(
               "ConfirmEmail", "Account", 
               new { userId = user.Id, code = code }, 
               protocol: Request.Url.Scheme);

Как кто-нибудь сделал часть пароля reset в веб-api? Мне нужна помощь.

4b9b3361

Ответ 1

Вы можете использовать Url.Link в Web API 2.0

var callbackUrl = Url.Link("Default", new { Controller = "Account", 
                  Action = "ConfirmEmail", userId = user.Id, code = code });

Ответ 2

Url.Action не существует, потому что помощник Url в sno snoA WebApi имеет метод Action. Вы можете использовать Url.Route вместо этого, чтобы генерировать то же самое, но вам нужно будет создать именованный маршрут, чтобы использовать этот метод. Если вы используете маршрутизацию атрибутов, вы можете добавить имя в атрибут маршрута, например:

[Route(Name="ConfirmEmail")]

а помощник будет

var callbackUrl = Url.Route("ConfirmEmail", new { userId = user.Id, code = code });

Ответ 3

Попробуйте следующее:

var code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
        var callbackUrl = Url.Action("ResetPassword", "Account", 
        new { UserId = user.Id, code = code }, protocol: Request.Url.Scheme);
        await UserManager.SendEmailAsync(user.Id, "Reset Password", 
        "Please reset your password by clicking here: <a href=\"" + callbackUrl + "\">link</a>");        
        return View("ForgotPasswordConfirmation");

Для получения дополнительной информации обратитесь к link

Ответ 4

Я создал простую форму "Изменить пароль", которой я управлял, на основе щелчка меню в моем приложении webAPI. В обработчике обновления для этой формы я создал следующий обработчик событий. Это просто вызывает веб-службу AccountController, которая поставляется с шаблоном WebAPI VS2013. В этом примере включена проверка подлинности и обратите внимание на конкретный Url, который будет использоваться для включения определенного маршрута в метод AccountController.

Найдите метод ChangePassword() в классе AccountController, сгенерированном в шаблоне WebAPI, чтобы узнать, что вызвано. Я думаю, что это должно ответить на ваш основной вопрос.

function updateHandler(callback) {
var response;
var targetUrl;

// disabled the login button to avoid multiple events
$("#btnLogin").prop('disabled', true);

var loginData = {
    grant_type: 'password',
    NewPassword: $("#txtNewPassword").val(),
    OldPassword: $("#txtOldPassword").val(),
    ConfirmPassword: $("#txtConfirmPassword").val()
};

var token = sessionStorage.getItem(tokenKey);
var headers = {};
if (token) {
    headers.Authorization = 'Bearer ' + token;
}


targetUrl = "/api/account/ChangePassword";

$.ajax({
    type: 'POST',
    url: targetUrl,
    data: loginData,
    headers: headers,
}).done(function (data) {
        closeChangePassword();
}).fail(function (xhr, textStatus, errorThrown) {
    passwordErrorHandler(xhr,0);
    // re-enable the login button 
    $("#btnLogin").prop('disabled', false);
});

}

Ответ 5

Вы не должны использовать Url.Link() или Url.Action(), чтобы отправить что-то пользователю, на мой взгляд. Вы подвергаете их возможному Host Header Attack -> Password Reset Poisoning.

Если IIS имеет привязку для приема соединений на 80/443, заголовок хоста может быть изменен и, в свою очередь, влияет на методы Url.Link() или Url.Action(). Если вы посмотрите на запрос, который я делаю ниже, я подключаюсь к http://hostheaderattack, но манипулирую заголовком host.

Доказательство концепции (PoC):

Url.Link:

public class TestController : ApiController
{
    public IHttpActionResult Get()
    {
        var callbackUrl = Url.Link("Default", new
        {
            Controller = "Home",
            Action = "Index",
        });

        return Ok(callbackUrl);
    }
}

введите описание изображения здесь

Url.Action:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Title = $"Url Created: {Url.Action("Index", "Home", "", Request.Url.Scheme)}";

        return View();
    }
}

введите описание изображения здесь

Я также продемонстрировал это здесь:

https://security.stackexchange.com/info/170755/host-header-attack-password-reset-poisoning-asp-net-web-api-2-hosted-as-az/170759#170759

Еще несколько прочтений о атаке заголовка хоста:

https://www.acunetix.com/blog/articles/automated-detection-of-host-header-attacks/

То, что вы должны делать, никогда не доверяет запросу пользователя и не строит URL-адрес хоста вручную.

Пример с именем ручного хоста для:

Url.Action: Url.Action("Index", "Home", null, Request.Url.Scheme, "example.com")

Для Url.Link это немного сложнее, но это можно сделать следующим образом:

public class TestController : ApiController
{
    // GET api/<controller>
    public IHttpActionResult Get()
    {
        var callbackUrl = Url.Link("Default", new
        {
            Controller = "Home",
            Action = "Index",
        });

        callbackUrl = ReplaceHost(callbackUrl, "example.com");

        return Ok(callbackUrl);
    }

    private string ReplaceHost(string original, string newHostName)
    {
        var builder = new UriBuilder(original);
        builder.Host = newHostName;
        return builder.Uri.ToString();
    }
}

Источник для метода ReplaceHost:

fooobar.com/info/56417/...