【问题标题】:Authorization denied message with FormsAuthentication带有 FormsAuthentication 的授权被拒绝消息
【发布时间】:2010-07-21 14:08:49
【问题描述】:

所以,我已经实现了我的 IPrincipal.IsInRole(...) 并且我正在像这样使用 FormsAuthentication:

<authentication mode="Forms">
     <forms loginUrl="Login.aspx" name="someName" timeout="600"/>
</authentication>

然后我有一个页面要求您进行身份验证并且您具有“roleA”。这是这样配置的:

 <location path="SomePage.aspx">
  <system.web>
   <authorization>
    <allow roles="roleA" />
    <deny users="*"/>
   </authorization>
  </system.web>
 </location>

现在,我登录到我的 Web 应用程序,但使用的用户没有角色 A。当我访问 SomePage.aspx 时,我被重定向到 Login.aspx,即表单元素的 loginUrl 中指定的 url。所以,我的问题是我不应该指定授权被拒绝消息或网址吗?如果用户已通过身份验证,但未授权,我为什么要重定向到登录页面。这让用户感到困惑。请告诉我我遗漏了一些简单的东西。

感谢阅读!

【问题讨论】:

    标签: asp.net forms-authentication authorization


    【解决方案1】:

    是的,这有点烦人。也许有人有一个更简单的想法,但我们想出的解决方案(hack?)是在用户被重定向到登录页面时寻找 ASP.NET 附加到查询字符串的最初请求的 URL。

    我们创建了一个新的 web.config 部分,其中存储了一组键/值,这些键/值与重定向 URL 的片段与授权消息相匹配:

    <configSections>
        <section name="authorizationFailureMessages" type="System.Configuration.NameValueSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        ...etc...
    </configSections>
    
    <authorizationFailureMessages>
        <add key="MemberResources" value="MembershipRequired" />
        <add key="Staff" value="StaffOnly" />
        <add key="Departments/Administration/BoardOfDirectors" value="BoardOfDirectorsOnly" />
        ...etc...
    </authorizationFailureMessages>
    

    在 Login.aspx 页面的 Page_Load() 事件中,我们调用一个方法,该方法使用此 URL 来确定发生了哪个(取消)授权事件,然后将它们重定向到显示适当文本的消息页面:

    private void DisplayAppropriateAuthorizationMessage ()
    {
        if ( !Page.User.Identity.IsAuthenticated )
            return;
    
        string redirectUrl = FormsAuthentication.GetRedirectUrl( Page.User.Identity.Name, false );
    
        if ( string.IsNullOrEmpty( redirectUrl ) )
            return;
    
        NameValueCollection authorizationFailureMessages = ConfigurationManager.GetSection( "authorizationFailureMessages" ) as NameValueCollection;
    
        if ( authorizationFailureMessages == null )
            return;
    
        foreach ( string key in authorizationFailureMessages.AllKeys )
        {
            if ( redirectUrl.Contains( key ) )
            {
                Response.Redirect( String.Format( "Message.aspx?{0}={1}", Constants.QueryStringKeys.ERRORMESSAGENAME, authorizationFailureMessages[ key ] ), true );
            }
        }
    }
    

    【讨论】:

    • 呃,这一定是正确的答案,因为我希望我不必诉诸于这样的事情:(虽然这有帮助,而且我觉得不那么愚蠢了。非常感谢!
    • 我仍然希望其他人想出了更聪明的方法。 :) 当然,理想的解决方案是如果 ASP.NET 公开(例如,在 Request 对象上)对导致授权失败的特定角色的引用。
    • 这不会为已获得授权但未登录并试图点击 URL 的用户显示未经授权的消息吗?
    • 确实如此,但我们只是相应地措辞措辞(即没有讨厌的“访问被拒绝!!”消息)。
    【解决方案2】:

    Roles.IsUserInRole - 如果您只是将它用于此页面,请将其放入后面的代码中。如果你有很多页面,你可以考虑把它放在一个基类中,然后从 web.config 或每页的数据库中读取。我相信这会给你最大的控制权。

    【讨论】:

      【解决方案3】:

      我基本上同意@MattPeterson 的解决方案。但我建议进行两项改进。

      1. 在我看来,你只是告诉“根据你的角色,你不能访问那个页面”,这就足够了。您不需要告诉需要哪些额外的角色,这将暴露您网站的授权管理细节。

      2. 可以从web.config(每个文件夹)获取访问控制列表,无需再写&lt;add key="MemberResources" value="MembershipRequired" /&gt;

      我相信你应该有类似的东西

      <authorization>
          <deny users="?" />
      </authorization
      

      在您的 web.config 中。

      【讨论】:

        猜你喜欢
        • 2018-11-16
        • 1970-01-01
        • 2017-11-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多