猿问

防止直接 url 访问剃刀页面处理程序

我制作了剃刀页面来注销用户。当经过身份验证的用户访问路由时/account/logout,我想向他显示带有成功消息的页面,如果用户是匿名的,则页面未授权。但是,不能通过直接 url 输入访问此成功页面。


以下代码运行良好,除了任何人都可以导航到/account/logout/success正常页面(并且由于它不负责注销,因此可能会造成混淆)。


public class LogoutModel : CustomPageModel

{

    private readonly SignInManager _signInManager;


    public LogoutModel(SignInManager signInManager) => _signInManager = signInManager;


    public async Task<IActionResult> OnGetAsync()

    {

        if (_signInManager.IsSignedIn(User))

        {

            await _signInManager.SignOutAsync();

            return RedirectToPage("Logout", "Success");

        }


        return Unauthorized();

    }


    public void OnGetSuccess()

    {

    }

}

如何防止直接访问处理程序 OnGetSuccess?


胡子哥哥
浏览 74回答 3
3回答

米琪卡哇伊

我已经通过使用检查 Referer 标头的 Attribute 和 IPageFilter 解决了这个问题。首先我创建了属性[AttributeUsage(AttributeTargets.Method)]public class ChildHandlerAttribute : Attribute{}然后我GetOnSuccess()用它装饰了处理程序[ChildHandler]public void OnGetSuccess(){}然后我实现了检查子处理程序的 Referer 标头的过滤器。public class ChildHandlerAsyncPageFilter : IAsyncPageFilter{&nbsp; &nbsp; public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var pageHandlerExecutedContext = await next();&nbsp; &nbsp; &nbsp; &nbsp; if (pageHandlerExecutedContext.HandlerMethod?.MethodInfo.GetCustomAttribute<ChildHandlerAttribute>() == null)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; var referrer = context.HttpContext.Request.Headers["Referer"].ToString();&nbsp; &nbsp; &nbsp; &nbsp; var request = pageHandlerExecutedContext.HttpContext.Request;&nbsp; &nbsp; &nbsp; &nbsp; if (!referrer.StartsWith($"{request.Scheme}://{request.Host}"))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pageHandlerExecutedContext.Result = new NotFoundResult();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) => Task.CompletedTask;}最后,我将过滤器添加到Startup.cs中的管道中services.AddMvc(options =>{&nbsp; &nbsp; options.Filters.Add<ChildHandlerAsyncPageFilter>();});

慕少森

请回答这个问题,了解它如何成为可能。不确定我是否建议走那条路,因为它有点脏而且是一个不必要的复杂解决方案。您可以为登录/注销用户返回不同的状态消息。注销.cshtml.cspublic class LogoutModel : CustomPageModel{&nbsp; &nbsp; private readonly SignInManager _signInManager;&nbsp; &nbsp; public LogoutModel(SignInManager signInManager) => _signInManager = signInManager;&nbsp; &nbsp; public string StatusMessage { get; set; }&nbsp; &nbsp; public async Task<IActionResult> OnGetAsync()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (_signInManager.IsSignedIn(User))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; await _signInManager.SignOutAsync();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StatusMessage = "Successfully logged out!";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Page();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StatusMessage = "Already logged out!";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Page();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}注销.cshtml@page@model X.LogoutModel@Model.StatusMessage

交互式爱情

在您的场景中,用户退出并重定向为匿名用户。所以不能说这里只有某些用户可以访问此操作。你应该用其他方式解决这个问题。比如你可以在Action中设置cookie中的值,LogOut然后在SuccessAction中签入。为了获得更多安全性,请应用 MVC 用于CSRF的模式。
随时随地看视频慕课网APP
我要回答