为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
胡子哥哥 2022-12-31 11:09:10
我制作了剃刀页面来注销用户。当经过身份验证的用户访问路由时/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?
查看完整描述

3 回答

?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

我已经通过使用检查 Referer 标头的 Attribute 和 IPageFilter 解决了这个问题。


首先我创建了属性


[AttributeUsage(AttributeTargets.Method)]

public class ChildHandlerAttribute : Attribute

{

}

然后我GetOnSuccess()用它装饰了处理程序


[ChildHandler]

public void OnGetSuccess()

{

}

然后我实现了检查子处理程序的 Referer 标头的过滤器。


public class ChildHandlerAsyncPageFilter : IAsyncPageFilter

{

    public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)

    {

        var pageHandlerExecutedContext = await next();


        if (pageHandlerExecutedContext.HandlerMethod?.MethodInfo.GetCustomAttribute<ChildHandlerAttribute>() == null)

        {

            return;

        }


        var referrer = context.HttpContext.Request.Headers["Referer"].ToString();

        var request = pageHandlerExecutedContext.HttpContext.Request;


        if (!referrer.StartsWith($"{request.Scheme}://{request.Host}"))

        {

            pageHandlerExecutedContext.Result = new NotFoundResult();

        }

    }


    public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) => Task.CompletedTask;

}

最后,我将过滤器添加到Startup.cs中的管道中


services.AddMvc(options =>

{

    options.Filters.Add<ChildHandlerAsyncPageFilter>();

});


查看完整回答
反对 回复 2022-12-31
?
慕少森

TA贡献2019条经验 获得超9个赞

请回答这个问题,了解它如何成为可能。

不确定我是否建议走那条路,因为它有点脏而且是一个不必要的复杂解决方案。您可以为登录/注销用户返回不同的状态消息。

注销.cshtml.cs

public class LogoutModel : CustomPageModel

{

    private readonly SignInManager _signInManager;


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


    public string StatusMessage { get; set; }


    public async Task<IActionResult> OnGetAsync()

    {

        if (_signInManager.IsSignedIn(User))

        {

            await _signInManager.SignOutAsync();

            StatusMessage = "Successfully logged out!";

            return Page();

        }

        else {

            StatusMessage = "Already logged out!";

            return Page();

        }


    }

}

注销.cshtml


@page

@model X.LogoutModel


@Model.StatusMessage


查看完整回答
反对 回复 2022-12-31
?
交互式爱情

TA贡献1712条经验 获得超3个赞

在您的场景中,用户退出并重定向为匿名用户。所以不能说这里只有某些用户可以访问此操作。

你应该用其他方式解决这个问题。比如你可以在Action中设置cookie中的值,LogOut然后在SuccessAction中签入。为了获得更多安全性,请应用 MVC 用于CSRF的模式。


查看完整回答
反对 回复 2022-12-31
  • 3 回答
  • 0 关注
  • 73 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信