Как предотвратить прямой доступ к просмотру в Asp.net Core - PullRequest
0 голосов
/ 07 февраля 2019

Я хочу предотвратить прямой доступ к представлению.У меня есть представление, которое отображает Email Confirmed, когда нажимается ссылка для подтверждения в электронном письме пользователя.Но проблема в том, что URL-адрес этого представления может быть доступен напрямую, я просто хочу, чтобы он был доступен при нажатии на ссылку в электронном письме.

Я пробовал эту опцию, но продолжаю получать ошибку, как UrlReferer недоступен в ядре Asp.net.этот код не будет работать в ядре asp.net, может кто-нибудь помочь мне, пожалуйста.

Как получить доступ к этим значениям в ASp.net Core 2.x:

filterContext.HttpContext.Request.UrlReferrer
filterContext.HttpContext.Request.Url.Host
filterContext.HttpContext.Request.UrlReferrer.Host

Код, который я нашел наПереполнение стека - но для этого нужен System.Web, который недоступен в ядре asp.net.


public class NoDirectAccessAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Request.UrlReferrer == null ||
                    filterContext.HttpContext.Request.Url.Host != filterContext.HttpContext.Request.UrlReferrer.Host)
            {
            filterContext.Result = new RedirectToRouteResult(new
                           RouteValueDictionary(new { controller = "Home", action = "Index", area = "" })); 
        }
    }
}

Рекомендуемый способ использования пользовательского атрибута

[NoDirectAccess]
public ActionResult MyActionMethod()

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

В общем случае не стоит полагаться на свойства "referer" в запросах.Реализации браузера могут отличаться, и в результате вы можете получить несовместимые значения.

Если URL-адрес «общедоступный», вы не можете запретить пользователю вводить его в браузере.Однако вы можете добавить проверку к запросу «Получить» - например, требуя дополнительную информацию об URL - в вашем случае, скажем, идентификатор пользователя и «код» проверки.Именно так удостоверение asp.net генерирует URL для подтверждения по электронной почте.Он включает в себя идентификатор пользователя и код подтверждения.Без этих значений в качестве части URL можно аннулировать запрос и перенаправить на другую страницу (а не на страницу, подтвержденную по электронной почте).

Например, на страницах Razor ниже приведен пример того, какВы можете подтвердить запрос.(Дело в том, что он требует дополнительного ввода от пользователя, а не простого URL-адреса ..) (Вы также можете сделать что-то подобное в MVC.)

       public async Task<IActionResult> OnGetAsync(string userId, string code)
        {
            if (userId == null || code == null)
            {
                return RedirectToPage("/Index");
            }

            var user = await _userManager.FindByIdAsync(userId);
            if (user == null)
            {
                throw new ApplicationException($"Unable to load user with ID '{userId}'.");
            }

            var result = await _userManager.ConfirmEmailAsync(user, code);
            if (!result.Succeeded)
            {
                throw new ApplicationException($"Error confirming email for user with ID '{userId}':");
            }

            return Page();
        }

URL-адрес для проверки приведенного выше кода будетбыть чем-то похожим на это:

http://[baseurl]/Account/ConfirmEmail?userId=ca5416dd-c93a-49a5-8fac-a9986dc91ed7&code=CfDJ8DWvHoaRg6JAv0rZ75jyEVx
0 голосов
/ 07 февраля 2019
  1. Если вам нужно UrlReferer, создайте фильтр следующим образом:
    public class NoDirectAccessAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var canAcess= false;

            // check the refer
            var referer= filterContext.HttpContext.Request.Headers["Referer"].ToString(); 
            if(!string.IsNullOrEmpty(referer)){
                var rUri = new System.UriBuilder(referer).Uri;
                var req = filterContext.HttpContext.Request;
                if(req.Host.Host==rUri.Host && req.Host.Port == rUri.Port && req.Scheme == rUri.Scheme ){
                    canAcess=true;
                }
            }

            // ... check other requirements

            if(!canAcess){
                filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Home", action = "Index", area = "" })); 
            }
        }
    }

, и теперь вы можете украсить свой метод действия с помощью [NoDirectAccess]:

        [NoDirectAccess]
        public IActionResult Privacy()
        {
            return View();
        }
Не рекомендуется использовать Referer для авторизации запроса, потому что довольно легко подделать заголовок HTTP UrlReferer.

IMO, гораздо лучше хранить EmailConfirmed=true где-нибудь, когда пользователь нажимает ссылку подтверждения.И тогда вы можете проверить, равен ли EmailConfirmed true при проверке.

    public class NoDirectAccessAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var canAcess= false;

            // check the `EmailConfirmed` state

            // ... check other requirements

            if(!canAcess){
                filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Home", action = "Index", area = "" })); 
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...