当未经授权时如何将用户重定向到ASP.NET页面?

23

如果我的用户已经通过身份验证,但尝试访问他们没有权限访问的页面(由于角色等原因),则需要将其重定向到AuthError.aspx页面(“您无权访问此页面”)。如果我这样设置web.config:

<authentication mode="Forms">
  <forms loginUrl="~/Account/Login.aspx" timeout="2880" />
</authentication>

系统的行为是错误的,因为用户已经通过身份验证,没有必要将他或她重定向到此页面。但是如果我在这里写AuthError.aspx而不是Login.aspx,我该如何将尚未经过身份验证的用户重定向到登录页面?


2
我理解你的痛苦。我也以为这个问题会很容易解决,但是我也没有找到解决方案。我不希望已经登录但未经授权的用户看到登录页面。 - Ishmael Smyrnow
看看这篇文章。 https://dev59.com/eW7Xa4cB1Zd3GeqPmST_?rq=1 - Nishant
6个回答

24

在您的登录页面的Page_Load事件中,您需要检查用户是否已通过身份验证,如果已通过身份验证,则将其重定向到访问被拒绝的页面:

protected void Page_Load(object sender, EventArgs e)
{
    if (User.Identity.IsAuthenticated) // if the user is already logged in
    {
            Response.Redirect("~/AccessDenied.aspx");
    }
}

如果您想让它更加高级一些,您可以检查ReturnUrl参数以确定用户是否直接访问该页面(例如通过将书签保存到登录页面),并对其进行不同的处理。以下是一个示例:

protected void Page_Load(object sender, EventArgs e)
    {
        if (User.Identity.IsAuthenticated)
        {

            // if they came to the page directly, ReturnUrl will be null.
            if (String.IsNullOrEmpty(Request["ReturnUrl"]))
            {
                 /* in that case, instead of redirecting, I hide the login 
                    controls and instead display a message saying that are 
                    already logged in. */
            }
            else
            {
            Response.Redirect("~/AccessDenied.aspx");
            }
        }
    }

3
+1 因为这个解决方案可以起作用。但是这是最好的解决方案吗? - Ananth
非常好 - 完美地工作了。谢谢。 - Bob Moss
在这种情况下,经过身份验证的用户将被重定向到AccessDenied页面...但这将适用于所有用户。如果我是管理员并且需要访问该页面怎么办?如果我尝试访问该页面,它仍然会将我重定向到AccessDenied...!!! - Lucky
@Lucky - 你可以再加一个检查,看看用户是否是管理员,如果是,就做一些其他的事情,而不是重定向到访问被拒绝的页面。 - Joel Beckham
@Lucky -- 尽管如此,拒绝访问页面只有在用户被重定向到登录页时才会显示,而不是直接访问该页面。用户被重定向到登录页的唯一原因是他们未被授权查看所请求的页面。如果您是管理员,是否会有任何情况下您未被授权访问而因此被重定向到登录页面? - Joel Beckham
显示剩余3条评论

2
对于我来说,最少麻烦、最大利益的解决方案是在“Login.aspx”页面中创建另一个部分(面板),并在经过身份验证(例如登录)的用户访问时显示“拒绝访问”,而不是登录表单。当已登录的用户进入该页面时,通常意味着他们无权访问将其重定向到此处的页面。
在登录页面上,我使用以下非常简单的代码来切换面板和登录表单的可见性:
if (Request.IsAuthenticated)
{
    LoginUser.Visible = false;
    AccessDeniedPanel.Visible = true;
}

这很简单,而且它有效。


1
你需要做以下事情:
1)启用角色(在web.config中):(将“xxx”替换为您自己的值)
<roleManager enabled="true">
  <providers>
    <clear />
    <add connectionStringName="ApplicationServices" applicationName="xxx"
      name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" />
    <add applicationName="xxx" name="AspNetWindowsTokenRoleProvider"
      type="System.Web.Security.WindowsTokenRoleProvider" />
  </providers>
</roleManager>

2) 你需要限制特定角色访问你网站的某些区域。我今天已经回答了另一个问题,其中解释了如何实现这一点。这里是链接。


谢谢,但所有这些事情都已经完成了。也许我描述得不太清楚,但问题是我使用角色和本地Web配置文件来保护文件夹,但我不知道如何将试图访问无法访问的文件夹的用户重定向到正确的AuthError.aspx页面。 - mimic

1
你需要区分认证和授权。你的代码片段解决了前者(“我是否为该站点所知”),但未解决后者(“我是否被允许访问此页面”)。
正如@santiagoIT建议的那样,角色可能是实现所需授权的最佳解决方案。一些控件,例如LoginView,具有角色感知和身份验证感知功能,因此您可以使用这些控件根据用户所在的角色显示不同的内容。
常见的方法是向不同角色的用户显示不同的菜单,以便他们只能看到与其角色相关的菜单- LoginView通常用于此目的。
或者,您可以使用LoginView控制单个页面上内容的可见性,以便未经身份验证的用户获得一条消息,已经过身份验证但无权查看页面的用户获得第二条消息,而已经过身份验证且被允许查看页面的用户则可以看到内容。
如果您只想重定向已通过身份验证但没有所需访问权限的用户,则还可以检查用户是否属于适当的角色(Roles.IsUserInRole),如果不是,则重定向到“您无权访问...”页面。
如果您真的很注重安全性,您可能希望将受限菜单/视图方法与每个页面上的授权检查相结合。

感谢您的回答,但我更喜欢不编写代码来实现此行为,而是使用web.config进行实现。当然,我可以在后台代码中检查可访问性,但我希望仅使用web.config来完成检查。 - mimic

0
尝试这个:
假设你只希望管理员用户能够访问你指定的页面,那么在页面加载时,你可以写下以下代码:
if (User.Identity.IsAuthenticated)
{
   if ( !User.IsInRole("Admin"))
   {
        Server.Transfer("~/AccessDeniedPage.aspx");
   }

}

如果你正在使用路由,你可以这样做:

if (User.Identity.IsAuthenticated)
{
   if ( !User.IsInRole("Admin"))
   {
        Response.RedirectToRoute("AccessDeniedRoute");
   }

}

-1
您可以像这样设置自定义错误页面:

<system.web>
  <customErrors mode="On">        
    <error statusCode="403" redirect="AuthError.aspx" />      
  </customErrors>
</system.web>

1
很遗憾,它不起作用。如果我使用它,它会再次打开登录页面,而不是重定向到AuthError.aspx =( - mimic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接