使用FormsAuthentication授权拒绝消息

时间:2010-07-21 14:08:50

标签: asp.net forms-authentication authorization

所以,我已经实现了我的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应用程序,但是没有使用roleA的用户。当我访问SomePage.aspx时,我被重定向到Login.aspx,这是在forms元素的loginUrl中指定的url。那么,我的问题是我不应该指定授权被拒绝的消息或网址吗?如果用户已通过身份验证但未获得授权,我为什么要重定向到登录页面。这对用户来说太混乱了。请告诉我,我错过了一些简单的事情。

感谢阅读!

3 个答案:

答案 0 :(得分:1)

是的,这有点烦人。也许有人有一个更简单的想法,但我们提出的解决方案(黑客?)是在用户被重定向到登录页面时查找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来确定发生了哪个(un)授权事件,然后将它们重定向到显示相应文本的消息页面:

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 );
        }
    }
}

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

  1. 在我看来,你只是说“根据你的角色,你不能访问那个页面”,这就足够了。您无需知道需要哪些额外角色,这将揭示您网站的授权管理的详细信息。

  2. 您可以从web.config获取访问控制列表(在每个文件夹中),而无需再次编写<add key="MemberResources" value="MembershipRequired" />

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

    <authorization>
        <deny users="?" />
    </authorization
    
    你的web.config中的